BZOJ3511: 土地劃分(最小割)
Description
Y國有N座城市,並且有M條雙向公路將這些城市連接起來,並且任意兩個城市至少有一條路徑可以互達。
Y國的國王去世之後,他的兩個兒子A和B都想成為新的國王,但他們都想讓這個國家更加安定,不會用武力解決問題。
於是他們想將這個國家分成兩個小國家A國和B國。現在,A擁有1號城市,B擁有N號城市,其他的城市還尚未確定歸屬哪邊(劃分之後的國家內部城市可以不連通)。
由於大家都想讓國家變得更好,而某些城市的人民願意國王的A兒子作為他們的領袖,而某些城市更看好B,而為了交通的便捷,如果劃分後的公路連接兩個同一個國家的城市,那麽更利於城市之間的交流。於是大臣們設計了一種對土地劃分的評分機制,具體如下:
1. 對於城市i,如果它劃分給A國,將得到VA[i]的得分;劃分給B國,將得到VB[i]的得分。
2. 對於一條公路i,如果它連接兩個A國的城市,將得到EA[i]的得分;連接兩個B國的城市,將得到EB[i]的得分;否則,這條公路將失去意義,將扣除EC[i]的得分。
現請你找到最優的土地劃分,使得這種它的評分最高。
Input
第一行包含兩個整數N,M,含義如問題描述所示。
接下來一行N-2個非負整數,表示VA[2..N-1]。
接下來一行N-2個非負整數,表示VB[2..N-1]。
接下來M行,每行五個非負整數描述一條公路:X Y EA[i] EB[i] EC[i],含義如問題描述所示。
Output
輸出有且僅有一個整數,表示最高評分。
Sample Input
3 38
9
1 2 2 6 2
2 3 8 5 7
1 3 9 4 1
Sample Output
11【樣例說明】
A國僅有1號點,B國有2號和3號點。
評分=VB[2]+EB[2]-EC[1]-EC[3]=9+5-2-1=11。
HINT
【數據說明】
數據點 N M 備註
1-2 <=20 <=200 無
3-4 <=5000 <=10000 VA、VB、EA、EB均為0
5-6 <=5000 <=10000 EC均為0
7-10 <=10000 <=40000 無
保證運算過程中及最終結果不超過32位帶符號整數類型的表示範圍
解題思路:
二者必取其一,這個很有最小割的意思,所以相當於將A國是源點,B國為匯點
對於一個點$P_i$,設其分到A國的價值為$V_{ai}$,分到B國的價值為$V_{bi}$。
取A則無法取B,這就是最小割模型了。
那麽從源點連向$P_{i}$一條有向邊,容量為$V_{ai}$,那麽從$P_i$向匯點一條有向邊,容量為$V_{bi}$,
這樣點的二選一就實現了,只需要用$\sum{V_{ai}+V_{bi}}$減去最小割就可以啦。
下面是邊的三選一:(設一條邊連A國城市貢獻為$C_{ai}$,連B國城市貢獻為$C_{bi}$,連接兩個國家點懲罰為$C_{ci}$)
兩個點若都選A,那麽就需要割去這條邊連接B國兩個城市點貢獻。
選A相當於割去城市選B國點貢獻,那麽相當於在匯點端取消了流量。
那麽現在限制一下,要求其取消匯點端流量則必須取消這條邊流量。
那麽就相當於在原來兩個城市向匯點連邊處向匯點重新連邊。
由於兩個點都必須限制,那麽相當於在兩個點都向匯點連$\frac{C_{bi}}{2}$的邊。
同理從源點連向邊的兩端點$\frac{C_{ai}}{2}$的邊。
所以在答案上加上$\sum{C_{ai}+C_{bi}}$最後減去最小割。
考慮懲罰條件。
此時為邊的兩端一個割源,一個割匯。
此時為了保證出現割,保留與匯點連邊端必須斷開所有與源點連邊。
所以此時最小割中一定存在$\frac{C_{ai}}{2}$,也就是這條邊存在時與源點的附加邊。
同理,最小割中也存在$\frac{C_{bi}}{2}$,這樣割下來的代價為$\frac{C_{bi}}{2}+\frac{C_{ai}}{2}$
但是我們期望其扣除的代價為$C_{ai}+C_{bi}+C_{ci}$,這就要求我們同時要割下一條代價為$\frac{C_{bi}}{2}+\frac{C_{ai}}{2}+C_{ci}$的邊。
可是這條邊應該加在哪裏呢。
考慮什麽樣的邊一定被割掉,一定是當前存在的與源點連邊的點連向一個與匯點有流量的點。
那麽就是在當前邊兩端對應的點間加一雙向邊,邊權為$\frac{C_{bi}}{2}+\frac{C_{ai}}{2}+C_{ci}$。
證明這樣做的可行性。
因為當兩端選同一個國家時,中間的流量不會流向匯或不會與源有流量。
所以這條附加邊在兩端選同一國家時是不會存在流量的,更不會被割去。
所以建圖就是這樣了。
因為有系數$\frac{1}{2}$的存在,將所有邊權*2,最後/2,可以證明最後一定是整除的,沒有必要擔心。
全圖最小割就好了。
代碼:
1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 const int oo=0x3f3f3f3f; 6 struct pnt{ 7 int hd; 8 int lyr; 9 int now; 10 }p[100000]; 11 struct ent{ 12 int twd; 13 int lst; 14 int vls; 15 }e[1000000]; 16 int cnt; 17 int n,m; 18 int s,t; 19 std::queue<int>Q; 20 void ade(int f,int t,int v) 21 { 22 cnt++; 23 e[cnt].twd=t; 24 e[cnt].vls=v; 25 e[cnt].lst=p[f].hd; 26 p[f].hd=cnt; 27 return ; 28 } 29 bool Bfs(void) 30 { 31 while(!Q.empty()) 32 Q.pop(); 33 for(int i=1;i<=t;i++) 34 p[i].lyr=0; 35 p[s].lyr=1; 36 Q.push(s); 37 while(!Q.empty()) 38 { 39 int x=Q.front(); 40 Q.pop(); 41 for(int i=p[x].hd;i;i=e[i].lst) 42 { 43 int to=e[i].twd; 44 if(p[to].lyr==0&&e[i].vls>0) 45 { 46 p[to].lyr=p[x].lyr+1; 47 if(to==t) 48 return true; 49 Q.push(to); 50 } 51 } 52 } 53 return false; 54 } 55 int Dfs(int x,int fll) 56 { 57 if(x==t) 58 return fll; 59 for(int& i=p[x].now;i;i=e[i].lst) 60 { 61 int to=e[i].twd; 62 if(p[to].lyr==p[x].lyr+1&&e[i].vls>0) 63 { 64 int ans=Dfs(to,std::min(fll,e[i].vls)); 65 if(ans>0) 66 { 67 e[i].vls-=ans; 68 e[((i-1)^1)+1].vls+=ans; 69 return ans; 70 } 71 } 72 } 73 return 0; 74 } 75 int Dinic(void) 76 { 77 int ans=0; 78 while(Bfs()) 79 { 80 for(int i=1;i<=t;i++) 81 p[i].now=p[i].hd; 82 int dlt; 83 while(dlt=Dfs(s,oo)) 84 ans+=dlt; 85 } 86 return ans; 87 } 88 int main() 89 { 90 // freopen("a.in","r",stdin); 91 scanf("%d%d",&n,&m); 92 s=n+1; 93 t=s+1; 94 int ans=0; 95 ade(s,1,oo); 96 ade(1,s,0); 97 ade(n,t,oo); 98 ade(t,n,0); 99 for(int i=2;i<=n-1;i++) 100 { 101 int x; 102 scanf("%d",&x); 103 x<<=1; 104 ade(s,i,x); 105 ade(i,s,0); 106 ans+=x; 107 } 108 for(int i=2;i<=n-1;i++) 109 { 110 int x; 111 scanf("%d",&x); 112 x<<=1; 113 ade(i,t,x); 114 ade(t,i,0); 115 ans+=x; 116 } 117 for(int i=1;i<=m;i++) 118 { 119 int x,y,a,b,c; 120 scanf("%d%d%d%d%d",&x,&y,&a,&b,&c); 121 ans+=a+b+a+b; 122 ade(s,x,a); 123 ade(x,s,0); 124 ade(s,y,a); 125 ade(y,s,0); 126 ade(x,t,b); 127 ade(t,x,0); 128 ade(y,t,b); 129 ade(t,y,0); 130 ade(x,y,a+b+c+c); 131 ade(y,x,a+b+c+c); 132 } 133 ans=(ans-Dinic())>>1; 134 printf("%d\n",ans); 135 return 0; 136 }
BZOJ3511: 土地劃分(最小割)