Codeforces Round #747 (Div. 2) D. The Number of Imposters(并查集,二分图)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #747 (Div. 2) D. The Number of Imposters(并查集,二分图)相关的知识,希望对你有一定的参考价值。

LINK

注意到当 A A A B B B是好人,无非两种情况.

Ⅰ. A A A是好人说真话,那么 B B B也是好人

Ⅱ. A A A是坏人说假话,那么 B B B也是坏人

抽象出来也就是 A , B A,B A,B属于同一类

而当 A A A B B B是坏人时,也就是 A , B A,B A,B属于不同的类

我们可以用并查集先对形如" A A A B B B是好人"这种关系处理

不断合并这些人,最后得到一些连通块,同一个连通块内的人要么都是好人好么都是坏人

再考虑形如" A A A B B B是坏人"这种关系,要求 A , B A,B A,B所在连通块恰好有一个是好人一个是坏人

于是我们可以把 A A A所在连通块缩成一个点, B B B连通块也是如此,权值为自身连通块大小

这样彼此连边,限制条件相当于是相邻点不能同时为坏人.

于是可以二分图染色,若染色出现矛盾无解.否则我们取白点和黑点权值和中较大的那个即可

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6+10;
vector<int>vec[maxn],v1,v2;
int n,m,flag,vis[maxn],siz[maxn],fa[maxn],col[maxn];
int find(int x){ return x==fa[x]?x:fa[x] = find( fa[x] ); }
void join(int l,int r)
{
	int fl = find( l ), fr = find( r );
	if( fl==fr )	return;
	fa[fl] = fr, siz[fr] += siz[fl]; siz[fl] = 0;
}
int res1,res2;
void dfs(int u,int type)
{
	vis[u] = 1; col[u] = type;
	res1 += type*siz[find(u)];  res2 += (type^1)*siz[find(u)];
	for(auto v:vec[u] )
	{
		if( vis[v] && col[v]!=( type^1 ) )	flag = 1;
		if( vis[v] )	continue;
		dfs(v,type^1);
	}
}
signed main()
{
	int t; cin >> t;
	while( t-- )
	{
		cin >> n >> m;
		for(int i=1;i<=n;i++)	siz[i] = 1, fa[i] = i;
		for(int i=1;i<=m;i++)
		{
			int l,r; string s; cin >> l >> r >> s;
			if( s[0]!='i' )	join(l,r);
			else	v1.push_back( l ), v2.push_back( r );
		}
		int ans = 0; flag = 0;
		for(int i=0;i<v1.size();i++)
		{
			int l = v1[i], r = v2[i];
			int fl = find( l ), fr = find( r );
			if( find(l)==find(r) )	flag = 1;
			vec[fl].push_back( fr ); vec[fr].push_back( fl );
		}
		for(int i=1;i<=n;i++)
		{
			if( vis[find(i)] )	continue;
			res1 = res2 = 0;	dfs( find(i),0 );
			ans += max( res1,res2 );
		}
		if( flag )	ans = -1;
		cout << ans << endl;
		for(int i=1;i<=n;i++)
		{
			vec[i].clear(), vis[i] = 0, v1.clear(), v2.clear();
			siz[i] = fa[i] = 0;
		}
	}
}

以上是关于Codeforces Round #747 (Div. 2) D. The Number of Imposters(并查集,二分图)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #747 (Div. 2)B. Special Numbers

Codeforces Round #747 (Div. 2)B. Special Numbers

A. Consecutive Sum Riddle( Codeforces Round #747 (Div. 2))

Codeforces Round #747 (Div. 2) D题

Codeforces Round #747 (Div. 2) (21.10.9)

Codeforces Round #387 (Div. 2) 747F(数位DP)