【BZOJ】2140 穩定婚姻

【解析】Hash,離散化,Tarjan

[分析]
對於每個名字,首先離散化成編號。
用hash或者其他,反正不要最基本的就行了,否則O(N^2L)會爆掉。
然後請參考:http://www.cnblogs.com/Randolph87/p/3757817.html

[吐槽]
難得吐槽一下,做這道題竟然做了一個上午,開始暴力求標號,然後一直TLE。
中間map的數據範圍少開了N,也試過幾次WA。
這不是水題嗎,爲什麼會是一個艱難的Accept...

[小結]
求二分圖完備匹配的必要邊,①存不存在增廣環? O(N^2) ②直接試着刪去按照hungery找完備匹配 O(N^3)。

[代碼]
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;

typedef unsigned long long ULL;
const int N=8002;
const int M=20001;
const int L=12;
const int T=37;
const int LMT=100009;

int n,m;
struct G
{
	int v,nxt;
}map[M+N];
int tt,hd[N];
int dfn[N],pre[N],ct;
int edge[N][2];
int v[N],color[N],stk[N],cc;
char t[L];
struct T
{
	char s[L];
	int nxt;
}hash[N];
int num,hh[LMT];

inline void ins(int u,int v)
{
	map[++tt].v=v;
	map[tt].nxt=hd[u];
	hd[u]=tt;
}

void tarjan(int now)
{
	dfn[now]=pre[now]=++ct;
	stk[++stk[0]]=now,v[now]=1;
	for (int k=hd[now];k;k=map[k].nxt)
	{
		if (v[map[k].v]==2) continue;
		if (v[map[k].v]==1) 
		{
			if (pre[map[k].v]<dfn[now]) dfn[now]=pre[map[k].v];
			continue;
		}
		tarjan(map[k].v);
		if (dfn[map[k].v]<dfn[now]) dfn[now]=dfn[map[k].v];
	}
	if (pre[now]==dfn[now])
	{
		cc++;
		for (;stk[stk[0]]!=now;stk[0]--)
			color[stk[stk[0]]]=cc,v[stk[stk[0]]]=2;
		color[stk[stk[0]]]=cc; v[stk[stk[0]--]]=2;
	}
}

inline ULL h(void)
{
	ULL sum=0; int lt=strlen(t);
	for (int i=0;i<lt;i++) sum=sum*T+t[i]-'0';
	return sum;
}

int pos(void)
{
	int key=h()%LMT;
	for (int k=hh[key];k;k=hash[k].nxt)
		if (!strcmp(hash[k].s,t)) return k;
	memmove(hash[++num].s,t,sizeof t);
	hash[num].nxt=hh[key];
	return hh[key]=num;
}

int main(void)
{	
	int t1,t2;
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",t); t1=pos();
		scanf("%s",t); t2=pos();
		edge[i][0]=t1,edge[i][1]=t2;
		ins(t1,t2);
	}
	scanf("%d",&m);
	for (int i=1;i<=m;i++)
	{
		scanf("%s",t); t1=pos();
		scanf("%s",t); t2=pos();
		ins(t2,t1);
	}
	
	for (int i=1;i<=n;i++)
		if (!v[edge[i][0]]) tarjan(edge[i][0]);
	
	for (int i=1;i<=n;i++)
		printf("%s\n",color[edge[i][0]]==color[edge[i][1]]?"Unsafe":"Safe");
	
	return 0;
}
發佈了137 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章