#Tarjan#洛谷 1407 [國家集訓隊]穩定婚姻
阿新 • • 發佈:2020-11-03
分析
如果婚姻安全那麼兩個點不在同一個強連通分量,
考慮強制定方向,夫妻女向男連邊,情侶男向女連邊,
這樣就直接用Tarjan有向圖縮點就可以了
程式碼
#include <iostream> #include <string> #include <stack> #include <map> #define rr register using namespace std; const int N=8011; stack<int>stac; map<string,int>uk; struct node{int y,next;}e[N<<2]; string S,T; int as[N],low[N],dfn[N],col[N],k,v[N],n,tot,cnt,m; inline void add(int x,int y){e[++k]=(node){y,as[x]},as[x]=k;} inline void tarjan(int x){ dfn[x]=low[x]=++tot; stac.push(x); v[x]=1; for (rr int i=as[x];i;i=e[i].next) if (!dfn[e[i].y]){ tarjan(e[i].y); low[x]=min(low[x],low[e[i].y]); } else if (v[e[i].y]) low[x]=min(low[x],dfn[e[i].y]); if (dfn[x]==low[x]){ ++cnt; rr int y; do{ y=stac.top(); stac.pop(); v[y]=0; col[y]=cnt; }while (x!=y); } } signed main(){ ios::sync_with_stdio(0), cin.tie(0),cout.tie(0); cin>>n; for (rr int i=1;i<=n;++i) cin>>S>>T,add(uk[S]=i,uk[T]=i+n); cin>>m; for (rr int i=1;i<=m;++i) cin>>S>>T,add(uk[T],uk[S]); for (rr int i=1;i<=n*2;++i) if (!dfn[i]) tarjan(i); for (rr int i=1;i<=n;++i) if (col[i]^col[i+n]) cout<<"Safe"<<endl; else cout<<"Unsafe"<<endl; return 0; }