题目大意:给定n对夫妻关系,再给定m对情人关系。如果在第i对夫妻离婚的前提下,这些人仍然能组成n对夫妻,就称i这个婚姻是不稳定的。要求判断所有的婚姻稳不稳定
设大写字母为男性
则一对婚姻是不稳定的当且仅当A与a离婚,a与B情人,b与C情人,c与D情人.....x与A情人
也就是说,假如把这张图看成一个二分图的话,对于所有婚姻关系从A向a连边,对于所有情人关系从a向A连边,假如能找到一个包含A和a的环,那么这对婚姻就是不稳定的
这一步我们可以先tarjan,然后检查这两个点是否在一个强连通分量里来解决
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define N 8010
#define M 30010
using namespace std;
map<string,int>p;
int to[M],nxt[M],pre[N],cnt;
void ae(int ff,int tt)
{
cnt++;
to[cnt]=tt;
nxt[cnt]=pre[ff];
pre[ff]=cnt;
}
int dfn[N],low[N],cn;
int q[N],t,b[N],c;
bool zai[N];
void tarjan(int x)
{
cn++;
dfn[x]=cn;
low[x]=cn;
t++;q[t]=x;
zai[x]=true;
int i,j;
for(i=pre[x];i;i=nxt[i])
{
j=to[i];
if(!dfn[j])
{
tarjan(j);
low[x]=min(low[x],low[j]);
}
else if(zai[j]) low[x]=min(low[x],dfn[j]);
}
if(low[x]==dfn[x])
{
c++;
while(q[t]!=x)
{
b[q[t]]=c;
zai[q[t]]=false;
t--;
}
b[x]=c;
zai[x]=false;
t--;
}
}
int main()
{
int n,m;
scanf("%d",&n);
int i,j,x,y;
string s;
for(i=1;i<=n;i++)
{
cin>>s;
p[s]=2*i-1;
x=p[s];
cin>>s;
p[s]=2*i;
y=p[s];
ae(x,y);
}
scanf("%d",&m);
for(i=1;i<=m;i++)
{
cin>>s;
x=p[s];
cin>>s;
y=p[s];
ae(y,x);
}
for(i=1;i<=2*n;i++)
if(!dfn[i]) tarjan(i);
for(i=1;i<=2*n;i+=2)
{
if(b[i]==b[i+1]) puts("Unsafe");
else puts("Safe");
}
}