題目大意:
給定n個點m條邊的無向簡單聯通圖G,邊有邊權。保證沒有重邊和自環。
定義一條簡單路徑的權值爲路徑上所有邊邊權的異或和。
保證G中不存在簡單環使得邊權異或和不爲00。
Q次詢問x到y的最短簡單路徑。
解題思路:
我是跑了遍SPFA 每次查詢的答案就是dis[x] xor dis[y]
要卡SPFA的話會T但是沒卡
我們可以dfs一遍求出每個點到1的距離然後O(1)查詢
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 100005;
struct Line {
int to, w, next;
}e[N<<2];
int n, m, q, cnt;
int vis[N], dis[N], last[N];
inline void add(int x, int y, int w) {
e[++cnt] = (Line){y, w, last[x]}; last[x] = cnt;
}
void spfa() { //把這裏換成dfs就是O(n + m)(SPFA真香)
memset(vis, 0, sizeof vis);
for (int i = 1; i <= n; ++i) dis[i] = 1 << 30;
queue <int> q; q.push(1);
dis[1] = 0, vis[1] = 1;
while (q.size()) {
int u = q.front(); q.pop(), vis[u] = 0;
for (int i = last[u]; i; i = e[i].next) {
int v = e[i].to;
if (dis[v] > (dis[u] ^ e[i].w)) {
dis[v] = dis[u] ^ e[i].w;
if (!vis[v])
q.push(v), vis[v] = 1;
}
}
}
}
int main() {
scanf("%d %d %d", &n, &m, &q);
for (int i = 1, x, y, w; i <= m; ++i)
scanf("%d %d %d", &x, &y, &w),
add(x, y, w), add(y, x, w);
spfa();
while (q--) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", dis[x] ^ dis[y]);
}
}