题目大意:给出一个递归函数,问这个递归函数最多能递归几层
解题思路:二分枚举递归层数,然后依此建边
如果给出的c[i]为0时,那么x[a[i]]和x[b[i]]中的其中一个要为真,连边即为 !a[i]->b[i], !b[i] -> a[i]
如果给出的c[i]为1时,那么x[a[i]]和x[b[i]]两个要么都为真,要么都为假,连边即为a[i]->b[i], b[i]->a[i], !a[i]->!b[i], !b[i]->!a[i]
如果给出的c[i]为2时,那么x[a[i]]和x[b[i]]两个中的一个要为假
,连边即为a[i]->!b[i], b[i]->!a[i]
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define N 10010
#define M 410
struct Node {
int a, b, c;
}node[N];
vector<int> G[M];
bool mark[M];
int S[M];
int n, m, top;
void init() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &node[i].a, &node[i].b, &node[i].c);
}
}
bool dfs(int u) {
if (mark[u ^ 1])
return false;
if (mark[u])
return true;
mark[u] = true;
S[++top] = u;
for (int i = 0; i < G[u].size(); i++)
if (!dfs(G[u][i]))
return false;
return true;
}
void AddEdge(int x, int valx, int y, int valy) {
G[2 * x + valx].push_back(y * 2 + valy);
}
bool judge(int mid) {
for (int i = 0; i < 2 * n; i++)
G[i].clear();
for (int i = 1; i <= mid; i++) {
if (node[i].c == 0) {
AddEdge(node[i].a, 0, node[i].b, 1);
AddEdge(node[i].b, 0, node[i].a, 1);
}
else if (node[i].c == 1) {
AddEdge(node[i].a, 0, node[i].b, 0);
AddEdge(node[i].b, 0, node[i].a, 0);
AddEdge(node[i].a, 1, node[i].b, 1);
AddEdge(node[i].b, 1, node[i].a, 1);
}
else if (node[i].c == 2) {
AddEdge(node[i].a, 1, node[i].b, 0);
AddEdge(node[i].b, 1, node[i].a, 0);
}
}
memset(mark, 0, sizeof(mark));
for (int i = 0; i < 2 * n; i += 2) {
if (!mark[i] && !mark[i ^ 1]) {
top = 0;
if (!dfs(i)) {
while (top) mark[S[top--]] = false;
if (!dfs(i ^ 1))
return false;
}
}
}
return true;
}
void solve() {
int l = 1, r = m, mid;
while (l <= r) {
mid = (l + r) / 2;
if (judge(mid))
l = mid + 1;
else
r = mid - 1;
}
printf("%d\n", l - 1);
}
int main() {
int test;
scanf("%d", &test);
while (test--) {
init();
solve();
}
return 0;
}