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