洛谷P1407 稳定婚姻(tarjan)

题目链接:https://www.luogu.org/problemnew/show/P1407

题目意思:有n对夫妻,有m对前男女朋友关系(都是n对夫妻中的人),问每一对夫妻是否婚姻稳定?

婚姻不稳定是指这对夫妻离婚,分别和有旧情的前男女朋友结婚,仍可以使2*n个人构成n对夫妻。

思路:我们将所有 现在或曾经交往过的 男孩和女孩连接起来,可以发现出现了一些环,而处在环中的几对夫妻都可以更换伴侣,也就是题目中所说的婚姻不安全。那么我们找出这些环,判断哪些夫妻处在环中即可。

我们想到tarjan就可以,但是tarjan是在有向图上进行的。我们怎么将这个无向图连接呢?

我们将单向边表示全部信息,而只要夫妻和情人之间建图方向相反,就可以保留原有关系了。

这里是将:

夫妻之间:girlboy

情人之间:boygirl

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
map<string,int>b,g;
const int maxn=10005;
const int maxm=300005;
struct node{
    int u,v,next;
}e[maxm];
int h[maxn],vis[maxn],low[maxn],dfn[maxn];
int st[maxn],belong[maxn];
int n,m,cnt,tot,top,num;

void init()
{
    memset(vis,0,sizeof(vis));
    memset(h,-1,sizeof(h));
    memset(dfn,0,sizeof(dfn));
    memset(belong,0,sizeof(belong));
    cnt=tot=top=num=0;
}

void add(int u,int v)
{
    e[cnt].u=u;
    e[cnt].v=v;
    e[cnt].next=h[u];
    h[u]=cnt++;
}

void tarjan(int u)
{
    low[u]=dfn[u]=++tot;
    vis[u]=1;
    st[++top]=u;
    for(int i=h[u];i!=-1;i=e[i].next)
    {
        int v=e[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(vis[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u])
    {
        int t;
        num++;
        do{
            t=st[top--];
            vis[t]=0;
            belong[t]=num;
        }while(t!=u);
    }
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n;
    string boy,girl;
    init();
    for(int i=0;i<n;i++)
    {
        cin>>girl>>boy;
        b[boy]=i;
        g[girl]=i+n;
        add(i+n,i);
    }
    cin>>m;
    for(int i=0;i<m;i++)
    {
        cin>>girl>>boy;
        add(b[boy],g[girl]);
    }
    for(int i=0;i<2*n;i++)
        if(!dfn[i])
            tarjan(i);
    for(int i=0;i<n;i++)
    {
        if(belong[i]==belong[i+n])
            cout<<"Unsafe"<<endl;
        else
            cout<<"Safe"<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xiongtao/p/10638804.html