洛谷 P4151 BZOJ 2115 [WC2011]最大XOR和路径
//bzoj上的題面太丑了,導(dǎo)致VJ的題面也很丑,于是這題用洛谷的題面
題面描述
XOR(異或)是一種二元邏輯運(yùn)算,其運(yùn)算結(jié)果當(dāng)且僅當(dāng)兩個(gè)輸入的布爾值不相等時(shí)才為真,否則為假。 XOR 運(yùn)算的真值表如下(\(1\) 表示真, \(0\) 表示假):
而兩個(gè)非負(fù)整數(shù)的 XOR 是指將它們表示成二進(jìn)制數(shù),再在對(duì)應(yīng)的二進(jìn)制位進(jìn)行 XOR 運(yùn)算。
譬如 \(12\) XOR \(9\) 的計(jì)算過程如下:
故 \(12\) XOR \(9\) = 5$。
容易驗(yàn)證, XOR 運(yùn)算滿足交換律與結(jié)合律,故計(jì)算若干個(gè)數(shù)的 XOR 時(shí),不同的計(jì)算順序不會(huì)對(duì)運(yùn)算結(jié)果造成影響。從而,可以定義 \(K\) 個(gè)非負(fù)整數(shù) \(A_1,A_2,……,A_{K-1},A_K\)的 XOR 和為
\(A_1\) XOR \(A_2\) XOR …… XOR \(A_{K-1}\) XOR \(A_K\)
考慮一個(gè)邊權(quán)為非負(fù)整數(shù)的無(wú)向連通圖,節(jié)點(diǎn)編號(hào)為 \(1\) 到 \(N\),試求出一條從 \(1\) 號(hào)節(jié)點(diǎn)到 \(N\) 號(hào)節(jié)點(diǎn)的路徑,使得路徑上經(jīng)過的邊的權(quán)值的 XOR 和最大。
路徑可以重復(fù)經(jīng)過某些點(diǎn)或邊,當(dāng)一條邊在路徑中出現(xiàn)了多次時(shí),其權(quán)值在計(jì)算 XOR 和時(shí)也要被計(jì)算相應(yīng)多的次數(shù),具體見樣例。
輸入格式
輸入文件 xor.in 的第一行包含兩個(gè)整數(shù) \(N\) 和 \(M\), 表示該無(wú)向圖中點(diǎn)的數(shù)目與邊的數(shù)目。
接下來 \(M\) 行描述 \(M\) 條邊,每行三個(gè)整數(shù) \(S_i\), \(T_i\) , \(D_i\), 表示 \(S_i\) 與 \(T_i\) 之間存在一條權(quán)值為 \(D_i\) 的無(wú)向邊。
圖中可能有重邊或自環(huán)。
輸出格式
輸出文件 xor.out 僅包含一個(gè)整數(shù),表示最大的 XOR 和(十進(jìn)制結(jié)果)。
輸入輸出樣例
輸入 #1
5 71 2 21 3 22 4 12 5 14 5 35 3 44 3 2輸出 #1
6說明/提示
【樣例說明】
如圖,路徑\(1 \rightarrow 2 \rightarrow 4 \rightarrow 3 \rightarrow 5 \rightarrow 2 \rightarrow 4 \rightarrow 5\)對(duì)應(yīng)的XOR和為
\(2\) XOR \(1\) XOR \(2\) XOR \(4\) XOR \(1\) XOR \(1\) XOR \(3 = 6\)
當(dāng)然,一條邊數(shù)更少的路徑\(1 \rightarrow 3 \rightarrow 5\)對(duì)應(yīng)的XOR和也是\(2\) XOR \(4 = 6\)。
【數(shù)據(jù)規(guī)模】
對(duì)于 \(20 \%\) 的數(shù)據(jù),\(N \leq 100,M \leq 1000,D_i \leq 10^{4}\);
對(duì)于 \(50 \%\) 的數(shù)據(jù),\(N \leq 1000,M \leq 10000,D_i \leq 10^{18}\);
對(duì)于 \(70 \%\) 的數(shù)據(jù),\(N \leq 5000,M \leq 50000,D_i \leq 10^{18}\);
對(duì)于 \(100 \%\) 的數(shù)據(jù),\(N \leq 50000\), \(M \leq 100000\),\(D_i \leq 10^{18}\)。
解題思路
看了題解可知,這題先dfs一遍圖,隨便找一條從起點(diǎn)到終點(diǎn)的路,求出路上的異或值,同時(shí)把所有搜索到的環(huán)的異或值全部加入線性基,然后把那條路上的異或值放到線性基里,找能夠異或到的最大值,然后就是答案。敷衍
這題的思想有點(diǎn)像我這學(xué)期高數(shù)剛學(xué)的格林公式,不知道的就別管這個(gè)詞了。我們從那條路起點(diǎn)\(1\)出發(fā),到達(dá)路中間的一個(gè)點(diǎn)\(x\),然后離開這條路,通過某一段 \(x \rightarrow y\) 走到某個(gè)環(huán)上的一個(gè)點(diǎn)\(y\),然后從點(diǎn)\(y\)開始繞環(huán)一周,回到點(diǎn)\(y\),再?gòu)狞c(diǎn)\(y\)通過剛才那段\(y \rightarrow x\) 回到點(diǎn)\(x\),再接著走完那條路剩下的部分\(x\rightarrow n\)。由“異或兩次同一個(gè)數(shù)相當(dāng)于沒有異或”的性質(zhì)可以知道,\(x\rightarrow y\)和\(y\rightarrow x\)就互相抵消了,于是答案就是\(1\rightarrow n\)的異或值再異或上那個(gè)環(huán)的異或值。再多走幾個(gè)環(huán),就再多異或幾個(gè)環(huán)就好。
那么為什么最開始隨便選一條路就好呢?是這樣:假設(shè)存在兩條路可以從\(1\)到\(n\),那么因?yàn)槭菬o(wú)向圖,這兩條路就成了一個(gè)環(huán),我們dfs過程中就會(huì)把這個(gè)環(huán)加入線性基。走了其中一條路,再走這個(gè)環(huán),就相當(dāng)于走了另一條路。
源代碼
#include<stdio.h>const int MAXN=5e5+5,MAXM=4e5+5; typedef long long ull; int n,m;struct Edge{int nxt,to;ull w; }e[MAXM<<1]; int cnt=1,head[MAXN]; inline void add(int u,int v,ull w) {e[cnt]={head[u],v,w};head[u]=cnt++;e[cnt]={head[v],u,w};head[v]=cnt++; }ull b[64]={0};//線性基 inline void addb(ull a) {for(int i=62;~i;i--){if(a>>i){if(b[i]) a^=b[i];else{b[i]=a;return;}}} } inline ull mx(ull ans) {for(int i=62;~i;i--)if((ans^b[i])>ans) ans^=b[i];return ans; } bool vis[MAXN]; ull dis[MAXN];//從1搜過來的值 void dfs(int u) {vis[u]=1;for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;if(vis[v])addb(dis[v]^dis[u]^e[i].w);else{dis[v]=dis[u]^e[i].w;dfs(v);}} } int main() {//freopen("test.in","r",stdin);scanf("%d%d",&n,&m);while(m--){int u,v;ull w;scanf("%d%d%lld",&u,&v,&w);add(u,v,w);}dfs(1);printf("%lld\n",mx(dis[n]));return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/wawcac-blog/p/11324239.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的洛谷 P4151 BZOJ 2115 [WC2011]最大XOR和路径的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北航考研攻略
- 下一篇: 重写Notification有感~~