CF845G Shortest Path Problem? [線性基]

傳送門

發現 1 -- n 的最小異或和路徑可以用某一條 1 -- n 的路徑 異或 隨便一些環的最小值表示

因爲如果走到那些環更優,我們可以先走到那個環,然後走一圈,再走回來

過去回來的貢獻會被抵消掉,於是我們可以處理出所有環的異或值插入線性基,然後查詢與 n 異或最小的即可

#include<bits/stdc++.h>
#define N 200050
using namespace std;
int first[N], nxt[N], to[N], w[N], tot;
void add(int x, int y, int z){
	nxt[++tot] = first[x], first[x] = tot;
	to[tot] = y, w[tot] = z;
}
int n, m;
bool vis[N]; int dis[N], A[50];
void Insert(int x){
	for(int i = 30; i >= 0; i--){
		if((1<<i) & x){
			if(A[i]) x ^= A[i];
			else { A[i] = x; break;}
		}
	}
}
void dfs(int u){
	vis[u] = true;
	for(int i=first[u];i;i=nxt[i]){
		int t = to[i];
		if(vis[t]) Insert(dis[t] ^ dis[u] ^ w[i]);
		else dis[t] = dis[u] ^ w[i], dfs(t);
	} 
}
int main(){
	scanf("%d%d", &n, &m);
	for(int i=1; i<=m; i++){
		int x, y, z; scanf("%d%d%d", &x, &y, &z);
		add(x, y, z); add(y, x, z);
	} dfs(1); 
	for(int i=30; i>=0; i--) if((dis[n] ^ A[i]) < dis[n]) dis[n] ^= A[i];
	printf("%d", dis[n]); return 0;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章