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(并查集,二分图)相关的知识,希望对你有一定的参考价值。
注意到当 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题