Solution

看了半天题解才看懂
我们先把边的异或转化成点的异或, 这里有个注意的坑
每一个点有两种取法, 总的是
但是对于边的取法, 因为对于他的两个端点, 都取反后边不改变, 所以对于边的取法是
这样我们就实现了连通图的任意环所有边权异或为0的总方案
但是题目的限定是有边权些已经给了值
对于一条已经被赋值的边
如果知道其中一个端点的值, 那么另一个端点也相应地被确定
因此我们可以从这个角度出发找寻是否有矛盾 解决不存在的子问题
接下来只需要先统计所有的连通块总点数贡献
然后除去那些被唯一确定的连通块贡献(假设连通块数量为 , 要除去

Code

/*
  autor: Kurisu
  2020年4月24日10:17:35
*/
#include<bits/stdc++.h>
using namespace std;

const long long inf = 1e18;
const int N = 5e5 + 5;
const double eps = 1e-10;
const int mod = 998244353;

struct Edge{
  int v, nextz, col;
}edge[N << 1];
int head[N], col[N], vis[N], tot, n, m, res, sum;

void addedge(int u, int v, int w) {
  edge[tot].v = v;
  edge[tot].nextz = head[u];
  edge[tot].col = w;
  head[u] = tot++;
}
bool dfs0(int u, int cor) {
  col[u] = cor;
  for (int i = head[u]; ~i; i = edge[i].nextz) {
    if(edge[i].col == -1) continue;
    int v = edge[i].v;
    if((col[v] != -1) && (cor ^ edge[i].col) != col[v]) return false;
    if((col[v] == -1) && !dfs0(v, cor ^ edge[i].col)) return false;
  }
  return true;
}
void dfs1(int u) {
  vis[u] = 1;
  sum++;
  for (int i = head[u]; ~i; i = edge[i].nextz) {
    int v = edge[i].v;
    if(!vis[v]) dfs1(v);
  }
}
bool dfs2(int u) {
  vis[u] = 1;
  res++;
  for (int i = head[u]; ~i; i = edge[i].nextz) {
    if(edge[i].col == -1) continue;
    int v = edge[i].v;
    if(!vis[v]) dfs2(v);
  }
  return true;
}
int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr);
  memset(head, -1, sizeof(head));
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    addedge(u, v, w);
    addedge(v, u, w);
  }
  memset(col, -1, sizeof(col));
  for (int i = 1; i <= n; i++) {
    if(col[i] == -1) {
      if(!dfs0(i, 1)) {
        cout << "0\n";
        return 0;
      }
    }
  }
  long long cnt = 0;
  for (int i = 1; i <= n; i++) {
    sum = 0;
    if(!vis[i]) {
      dfs1(i);
      cnt += sum - 1;
    }
  }
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= n; i++) {
    res = 0;
    if(!vis[i]) {
      dfs2(i);
      cnt = cnt - (res - 1);
    }
  }
  long long ans = 1;
  for (int i = 1; i <= cnt; i++) {
    ans = (ans * 2) % mod;
  }
  cout << ans << "\n";
  return 0;
}