rt,洛谷上挂到了 50pts,场上不记得怎么手动开大栈空间测不了最后一个大样例,但是现在只有 Win 电脑用开不了栈空间不知道怎么调,不知道怎么错了就是市面广传的二分图染色做法,拆点了然后连边表示这两个变量必须不同,求求了看看把/kk
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5 + 5;
int t, c, n, m, col[N], siz, useu, a[N], cnt, isu[N];
vector <int> G[N];
void addedge(int u, int v) {
//if(u < 1 || v < 1) cout << "md\n";
G[u].emplace_back(v), G[v].emplace_back(u);
//cnt += 2;
return ;
}
bool dfs(int u, int cur) {
col[u] = cur;
if (u <= n)
siz++;
if (isu[u])
useu = 1;
bool ret = 1;
for (int v : G[u]) {
if (col[v] == 0) {
if (!dfs(v, -cur))
ret = 0;
} else if (col[v] == cur)
ret = 0;
}
return ret;
}
void solve() {
cin >> n >> m;
memset(isu, 0, sizeof(isu));
memset(col, 0, sizeof(col));
for (int i = 0; i <= 2 * n + 1; ++i)
G[i].clear();
//多测清空
for (int i = 1; i <= n; ++i)
a[i] = i, addedge(i, i + n);
for (int i = 1, u, v; i <= m; ++i) {
char o;
cin >> o;
cin >> u;
if (o == '+') {
cin >> v;
a[u] = a[v];
}
if (o == '-') {
cin >> v;
a[u] = -a[v];
}
if (o == 'U')
a[u] = 0;
}
for (int i = 1; i <= n; ++i) {
if (a[i] == i)
continue;
else if (a[i] == -i || a[i] == 0)
isu[i] = isu[i + n] = 1;
else if (a[i] > 0)
addedge(i, a[i] + n), addedge(i + n, a[i]);
else
a[i] = -a[i], addedge(i, a[i]), addedge(i + n, a[i] + n);
}
int ans = 0;
for (int i = 1; i <= 2 * n; ++i) {
if (col[i] == 0) {
useu = siz = 0;
if (!dfs(i, 1) || useu)
ans += siz;
//cout << siz << "\n";
}
//cout << col[i] << ' ';
}
//cout << cnt << "\n";
cout << ans << "\n";
return ;
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> c >> t;
while (t--)
solve();
return 0;
}