题目链接
题意:按照顺序,对那些不安全的夫妻(就是那种生了气发了脾气就去找前男(女)友)的夫妻输出Unsalf!然后剩下的Salf!就是了。
假如只有一方会换,那是显然不行的,因为(会被抓*)的,所以只有当AB是夫妻,CD是夫妻,A的前男友是D,B的前女友是C的时候,他们就会发生“私奔”了!天呐,咋一看,就是Tarjan缩点嘛!
最后怎么输出呢,在同一个团中的夫妻,竟然是“Unsalf”夫妻!好了,就是Tarjan了。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 8e3 + 7, maxE = 4e4 + 7;
int N, M, head[maxN], cnt, tot, g[maxN], b[maxN];
map<string, int> mp;
string bi, gi;
struct Eddge
{
int nex, to;
Eddge(int a=-1, int b=0):nex(a), to(b) {}
}edge[maxE];
inline void addEddge(int u, int v)
{
edge[cnt] = Eddge(head[u], v);
head[u] = cnt++;
}
int dfn[maxN], low[maxN], Index, Stop, Stap[maxN], Belong[maxN], Bcnt;
bool instack[maxN];
inline void Tarjan(int u, int fa)
{
dfn[u] = low[u] = ++Index;
Stap[++Stop] = u;
instack[u] = true;
int v;
for(int i=head[u]; ~i; i=edge[i].nex)
{
v = edge[i].to;
if(!dfn[v])
{
Tarjan(v, u);
if(low[v] < low[u]) low[u] = low[v];
}
else if(instack[v] && dfn[v] < low[u]) low[u] = dfn[v];
}
if(low[u] == dfn[u])
{
Bcnt++;
do
{
v = Stap[Stop--];
Belong[v] = Bcnt;
instack[v] = false;
}while(u != v);
}
}
inline void init()
{
cnt = Index = Stop = Bcnt = 0;
}
int main()
{
scanf("%d", &N);
init();
for(int i=1; i<=N; i++)
{
cin>>gi>>bi;
if(!mp[gi])
{
mp[gi] = ++tot;
head[tot] = -1;
dfn[tot] =0;
instack[tot] = false;
}
if(!mp[bi])
{
mp[bi] = ++tot;
head[tot] = -1;
dfn[tot] =0;
instack[tot] = false;
}
addEddge(mp[bi], mp[gi]);
g[i] = mp[gi]; b[i] = mp[bi];
}
scanf("%d", &M);
for(int i=1; i<=M; i++)
{
cin>>gi>>bi;
if(!mp[gi]) mp[gi] = ++tot;
if(!mp[bi]) mp[bi] = ++tot;
addEddge(mp[gi], mp[bi]);
}
for(int i=1; i<=tot; i++) if(!dfn[i]) Tarjan(i, 0);
for(int i=1, u, v; i<=N; i++)
{
u = g[i]; v = b[i];
if(Belong[u] == Belong[v]) printf("Unsafe\n");
else printf("Safe\n");
}
return 0;
}