Luogu P1407 [国家集训队]稳定婚姻

Link
不稳定的定义就是一个男女相见的环。
对于每一对夫妻关系我们女\(\rightarrow\)男连边。
对于每一对情侣关系我们男\(\rightarrow\)女连边。
这样如果一对夫妻关系中的男女双方在同一个SCC的话,这对夫妻关系就是不稳定的。

#include<cstdio>
#include<vector>
#include<cctype>
#include<string>
#include<iostream>
#include<unordered_map>
using std::cin;
using std::string;
using std::vector;
using std::unordered_map;
const int N=8007;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
int min(int a,int b){return a<b? a:b;}
unordered_map<string,int>mp;
vector<int>e[N];
string s,t;
int n,m,T,top,cnt,dfn[N],low[N],ins[N],stk[N],bel[N];
void tarjan(int u)
{
    dfn[u]=low[u]=++T,stk[++top]=u,ins[u]=1;
    for(int v:e[u])
	if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
	else if(ins[v]) low[u]=min(low[u],dfn[v]);
    if(low[u]==dfn[u])
    {
	++cnt;
	do bel[stk[top]]=cnt,ins[stk[top]]=0; while(stk[top--]^u);
    }
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i) cin>>s>>t,e[mp[s]=i].push_back(mp[t]=i+n);
    m=read();
    for(int i=1;i<=m;++i) cin>>s>>t,e[mp[t]].push_back(mp[s]);
    for(int i=1;i<=n*2;++i) if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;++i) puts(bel[i]==bel[i+n]?"Unsafe":"Safe");
}
posted @ 2020-01-25 14:06  Shiina_Mashiro  阅读(100)  评论(0编辑  收藏  举报