首页 > 代码库 > BZOJ 2140 稳定婚姻

BZOJ 2140 稳定婚姻

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2140

题意:已知n对夫妻的婚姻状况,称第i对夫 妻的男方为Bi,女方为Gi。若某男Bi与某女Gj曾经交往过,则当某方与其配偶(即Bi与Gi或Bj与Gj)感情出现问题时,Bi与Gj有私奔的可能 性。不妨设Bi和其配偶Gi感情不和,于是Bi和Gj旧情复燃,进而Bj因被戴绿帽而感到不爽,联系上了他的初恋情人Gk……一串串的离婚事件像多米诺骨 牌一般接踵而至。若在Bi和Gi离婚的前提下,这2n个人最终依然能够结合成n对情侣,那么我们称婚姻i为不安全的,否则婚姻i就是安全的。给定所需信 息,你的任务是判断每对婚姻是否安全。

思路:将没对夫妻看做一个点,交往过的两个点两边。求强连通分量,强连通分量中的个数大于1则是不安全的

 

map<string,int> mp1,mp2;vector<int> g[N];int n,m;int low[N],dfn[N],id,color[N],size[N],num;stack<int> S;int visit[N];void DFS(int u){    dfn[u]=low[u]=++id;    S.push(u);        int i,v;    FOR0(i,SZ(g[u]))    {        v=g[u][i];        if(!dfn[v]) DFS(v),upMin(low[u],low[v]);        else if(!visit[v]) upMin(low[u],dfn[v]);    }    if(low[u]==dfn[u])    {        num++;        do        {            v=S.top();            S.pop();            visit[v]=1;            color[v]=num;            size[num]++;        }while(u!=v);    }}int main(){    RD(n);    string S;    int i;    FOR1(i,n)    {        RD(S); mp1[S]=i;        RD(S); mp2[S]=i;    }    RD(m);    int x,y;    FOR1(i,m)    {        RD(S); x=mp1[S];        RD(S); y=mp2[S];        g[x].pb(y);     }    FOR1(i,n) if(!visit[i]) DFS(i);    FOR1(i,n)    {        if(size[color[i]]==1) puts("Safe");        else puts("Unsafe");    }}