695.劣马

经典染色法判二分图1

因为需要把仇视的人分成两组,并且每组内的人员不得相互仇视;

所以这道题并非匹配,而是要我们判断给出的关系是否满足二分图。

名字用\(RBT\)存,每次查询 \(log n\)

时间复杂度:\(O( mlogn + 2*n )\)

#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=210, M=N*2;
int h[N],e[M],ne[M],idx=0;

void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
	e[idx]=a,ne[idx]=h[b],h[b]=idx++;
}

map<string,int> d;

int c[N];
bool dfs(int u,int color)
{
	c[u]=color;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(!c[j]&&!dfs(j,3-color)) return false;
		else if(c[j]==color) return false;
	}
	return true;
}

void init()
{
	memset(h,-1,sizeof h);
	memset(c,0,sizeof c);
	idx=0;
	d.clear();
}

int main()
{
	int T; cin>>T;
	for(int ith=1;ith<=T;ith++)
	{
		init();
		
		int cnt=0;
		int n; cin>>n;
		for(int i=0;i<n;i++)
		{
			string a,b; cin>>a>>b;
			if(!d.count(a)) d[a]=++cnt;
			if(!d.count(b)) d[b]=++cnt;
			
			add(d[a],d[b]);
		}
		
		bool flag=true;
		for(int i=1;i<=cnt;i++)
			if(!c[i])
				if(!dfs(i,1))
				{
					flag=false;
					break;
				}
		
		printf("Case #%d: ",ith);
		puts(flag?"Yes":"No");
	}
    return 0;
}

posted @ 2022-08-28 09:35  Sankano  阅读(27)  评论(0编辑  收藏  举报