BZOJ P2140 稳定婚姻【tarjan缩点】

板子:

#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define sg string
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=2e5+5;

ll n,m,cc;
ll cnt,to[N<<1],nxt[N<<1],head[N];
ll tot,num,top,dfn[N],low[N],bel[N],vis[N],stack[N];

map<string,ll>mp;

struct node {
	ll x,y;
}cp[N];

void ins(ll x,ll y) {
	to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt;
}

void tarjan(ll x) {
	dfn[x]=low[x]=++num;vis[x]=1;stack[++top]=x;
	for(ll i=head[x];i;i=nxt[i]) {
		ll y=to[i];
		if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
		else if(vis[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x]) {
		vis[x]=0;bel[x]=++tot;
		while(stack[top]!=x) {
			bel[stack[top]]=tot;
			vis[stack[top--]]=0;
		}top--;
	}
}

int main() {
	cin>>n;
	
	rep(i,1,n) {
		sg a,b;ll x,y;
		cin>>a>>b;
		if(!mp[a]) x=mp[a]=++cc;
		else x=mp[a];
		
		if(!mp[b]) y=mp[b]=++cc;
		else y=mp[b];
		
		ins(y,x);cp[i].x=x,cp[i].y=y;
	}
	
	cin>>m;
	
	rep(i,1,m) {
		sg a,b;ll x,y;
		cin>>a>>b;
		if(!mp[a]) x=mp[a]=++cc;
		else x=mp[a];
		
		if(!mp[b]) y=mp[b]=++cc;
		else y=mp[b];
		
		ins(x,y);
	}
	
	rep(i,1,cc) if(!dfn[i]) tarjan(i);
    
	rep(i,1,n) {
		if(bel[cp[i].x]==bel[cp[i].y]) puts("Unsafe");
		else puts("Safe");
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/82765557