tarjan判环,若一对夫妻在同一scc中则不稳定。
构造成有向图,
当前婚姻状况 女→男 连边,曾经交往的 男→女 连边。
代码如下
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<map> #define MogeKo qwq using namespace std; const int maxn = 1e5+10; int n,m,now,num,top,cnt; int head[maxn],to[maxn],nxt[maxn]; int dfn[maxn],low[maxn],sta[maxn],col[maxn]; bool insta[maxn]; char u[10],v[10]; map <string,int> id; void add(int x,int y) { to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt; } void tarjan(int u) { dfn[u] = low[u] = ++now; sta[++top] = u; insta[u] = true; for(int i = head[u]; i; i = nxt[i]) { int v = to[i]; if(!dfn[v]) { tarjan(v); low[u] = min(low[u],low[v]); } else if(insta[v]) low[u] = min(low[u],dfn[v]); } if(low[u] == dfn[u]) { col[u] = ++num; insta[u] = false; while(sta[top] != u) { int v = sta[top--]; col[v] = num; insta[v] = false; } top--; } } int main() { scanf("%d",&n); for(int i = 1; i <= n; i++) { scanf("%s%s",u,v); id[u] = i*2-1; id[v] = i*2; add(id[u],id[v]); } scanf("%d",&m); for(int i = 1; i <= m; i++) { scanf("%s%s",u,v); add(id[v],id[u]); } for(int i = 1; i <= n*2; i++) if(!dfn[i]) tarjan(i); for(int i = 1; i <= n; i++) if(col[i*2-1] == col[i*2]) printf("Unsafe "); else printf("Safe "); return 0; }