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");

    }

}

 

 

 

你可能感兴趣的:(ZOJ)