P1407 稳定婚姻

题面:https://www.luogu.org/problemnew/show/P1407

本题建图时:
夫妻之间:女孩指向男孩
情人之间:男孩指向女孩
然后Tarjan求强连通分量,对于一对夫妻,如果两人在同一个强连通分量里,那么这对婚姻就是不安全的,反之,则是安全的。 

Code:
# include <iostream>
# include <cstdio>
# include <map>
using namespace std;

const int N=8010;
const int M=20010;

int m,n;
string c1,c2;
map <string,int > a;
struct Edge
{
    int to,Next;
}edge[(M<<1)+N];
int head[N],cnt=1,is[(M<<1)+N];
int T=0,low[N],dfn[N],s[N],tot=0,ha[N],in[N],n0=0;

void add(int u,int v)
{
    edge[++cnt].Next=head[u];
    edge[cnt].to=v;
    head[u]=cnt;
}

void tarjan(int now)
{
    dfn[now]=low[now]=++T;
    in[now]=1;
    s[++tot]=now;
    for(int i=head[now];i;i=edge[i].Next)
    {
        int v=edge[i].to;
        if(!dfn[v])
        {
            tarjan(v);
            low[now]=min(low[now],low[v]);
        }
        else if(in[v])
            low[now]=min(low[now],dfn[v]);
    }
    if(dfn[now]==low[now])
    {
        n0++;int k;
        do
        {
            k=s[tot];
            tot--;
            ha[k]=n0;
            in[k]=0;
        }while(k!=now);
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        cin>>c1>>c2;
        a[c1]=i;
        a[c2]=n+i;
        add(i,n+i);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        cin>>c1>>c2;
        add(a[c2],a[c1]);
    }
    for(int i=1;i<=n<<1;i++)
        if(!dfn[i])
            tarjan(i);
    for(int i=1;i<=n;i++)
        if(ha[i]==ha[i+n])
            printf("Unsafe\n");
        else
            printf("Safe\n");
    return 0;
}
posted @ 2019-07-16 15:58  prestige  阅读(128)  评论(0编辑  收藏  举报