Codeforces Round #747 (Div.2) D. The Number of Imposters


題意:

\(n\)個人,每個人要么是敵人,要么是朋友。已知敵人一定說假話,朋友一定說真話,給出\(m\)句形如\(i,j,c\)的話,表示第\(i\)個人說第\(j\)個人的身份是\(c\)​,問敵人的最大可能數量是多少。

\(1\le n\le 2e5\)

題解:

\(2-SAT\)​只能判是否有解,找出的不是最優解

注意到如果A說B為朋友,那么A和B的身份是相同的(A假B也假,A真B也真),否則A和B身份相反(A假B真,A真B假)

也就是說,\(n\)個點中每個點要么是黑色,要么是白色,並且已知了一些關系(某些點顏色相同/相反),

建圖並黑白染色,使得染色方案沒有沖突(是二分圖)

在顏色相同的點之間連邊權0的邊,異色點之間連邊權為1的邊,每次要么把點染成0,要么染成1,dfs檢查染色是否按照(\(col[u] \ xor\ w(u,v)=col[v]\)​​),若不是則不合法

點與點之間的限制關系可以通過建圖連邊,然后在邊上dfs/bfs傳遞和檢查

// Problem: D. The Number of Imposters
// Contest: Codeforces - Codeforces Round #747 (Div. 2)
// URL: https://codeforces.com/contest/1594/problem/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 7;
#define ll long long
int n, m, k, tot;
int rd() {
	int s = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
	while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}
	return s * f;
}
struct edge {
	int v, w, nxt;
}e[1000007];
int head[maxn], eid, col[maxn], ans, ans1, ans2;
char str[20];
void init() {
	for (int i = 1; i <= n; i++) head[i] = col[i] = -1;
	eid = 0;
}
void insert(int u, int v, int w) {
	e[eid].v = v;
	e[eid].w = w;
	e[eid].nxt = head[u];
	head[u] = eid++;
}
void dfs(int u, int c) {
	col[u] = c;
	//printf("u == %d\n", u);
	if (c == 0) ans1++;
	else ans2++;
	for (int i = head[u]; ~i; i = e[i].nxt) {
		int v = e[i].v;
		if (col[v] == -1) {
			dfs(v, c^e[i].w);
		} else {
			if ((col[v]^col[u]) != e[i].w) {
				//printf("u v w == %d %d %d\n", u, v, e[i].w);
				ans = -999999999;
			}
		}
	}
}
int main() {
	int T = rd();
	while (T--) {
		n = rd(), m = rd();
		ans = 0;
		init();
		for (int i = 1; i <= m; i++) {
			int u = rd(), v = rd();
			scanf("%s", str);
			if (str[0] == 'i') {
				insert(u, v, 1);
				insert(v, u, 1);
			} else {
				insert(u, v, 0);
				insert(v, u, 0);
			}
		}
		for (int i = 1; i <= n; i++) {
			if (col[i] == -1) {
				ans1 = ans2 = 0;
				dfs(i, 0);
				ans += max(ans1, ans2);
			}
		}
		printf("%d\n", ans < 0 ? -1 : ans);
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM