题中有一句话:
保证 G 中不存在简单环使得边权异或和不为 0。
也就是说经过环时走的两条路的边权异或和为0,而题目求的是路径异或和,那么这两条路走哪边都是一样的
于是可以随便选一边,也就是不管环,直接bfs求路径,x,y之间任意路径是等价的
而且由于异或的性质,设dis[x]
为x到源点的路径异或和,那么x到y的路径异或和就是dis[x] ^ dis[y]
(因为从源点到x的路径是一样的,异或一下没了)
综上所述只要跑一遍bfs,把dis处理出来,就能处理所有的询问
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define N 100005
#define M 400005
int head[N], vis[N], dis[N];
int ver[M], w[M], nt[M];
int tot = 0;
int n, m, q;
void Add(int x, int y, int z)
{
tot++;
ver[tot] = y;
w[tot] = z;
nt[tot] = head[x];
head[x] = tot;
}
void bfs()
{
memset(vis, 0, sizeof vis);
for (int i = 2; i <= n; i++)
dis[i] = 100000000;
dis[1] = 0;
queue<int> q;
q.push(1);
while (q.size())
{
int x = q.front();
vis[x] = 1;
q.pop();
for (int i = head[x]; i; i = nt[i])
{
int y = ver[i];
if (!vis[y])
{
dis[y] = dis[x] ^ w[i];
q.push(y);
}
}
}
}
int main()
{
cin >> n >> m >> q;
for (int i = 0; i < m; i++)
{
int x, y, z;
cin >> x >> y >> z;
Add(x, y, z);
Add(y, x, z);
}
bfs();
while (q--)
{
int x, y;
cin >> x >> y;
cout << (dis[x] ^ dis[y]) << endl;
}
return 0;
}