【bzoj题解】1001 狼抓兔子
生活随笔
收集整理的這篇文章主要介紹了
【bzoj题解】1001 狼抓兔子
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
現在小朋友們最喜歡"喜羊羊與灰太狼",話說灰太狼抓羊不到,但抓兔子還是比較在行的,而且現在的兔子還比較笨,它們只有兩個窩,現在你做為狼王,面對下面這樣一個網格的地形: ?左上角點為(1,1),右下角點為(N,M)(上圖中N=3,M=4).有以下三種類型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的權值表示這條路上最多能夠通過的兔子數,道路是無向的。左上角和右下角為兔子的兩個窩,開始時所有的兔子都聚集在左上角(1,1)的窩里,現在它們要跑到右下角(N,M)的窩中去,狼王開始伏擊這些兔子。當然為了保險起見,如果一條道路上最多通過的兔子數為K,狼王需要安排同樣數量的K只狼,才能完全封鎖這條道路,你需要幫助狼王安排一個伏擊方案,使得在將兔子一網打盡的前提下,參與的狼的數量要最小。因為狼還要去找喜羊羊麻煩。 輸入 第一行為N,M.表示網格的大小,N,M均小于等于1000。 接下來分三部分 第一部分共N行,每行M-1個數,表示橫向道路的權值。 第二部分共N-1行,每行M個數,表示縱向道路的權值。 第三部分共N-1行,每行M-1個數,表示斜向道路的權值。 輸出 輸出一個整數,表示參與伏擊的狼的最小數量。 樣例輸入 3 4 5 6 44 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6 樣例輸出 14 題解 裸的最小割,我轉了轉最大流跑Dinic。 記得連雙向邊。發現當前弧優化很優秀…… 1 #include<cstdio> 2 #include<cstring> 3 #define F(i,a,b) for(int i=a;i<=b;++i) 4 #define F2(i,a,b) for(int i=a;i<b;++i) 5 #define v(a,b) ((a-1)*m+b) 6 int n,m,S,T; 7 int h[1000001],nxt[6000001],to[6000001],cap[6000001],tot=1; 8 inline void ins(int x,int y,int c){nxt[++tot]=h[x];to[tot]=y;cap[tot]=c;h[x]=tot;nxt[++tot]=h[y];to[tot]=x;cap[tot]=c;h[y]=tot;} 9 int iter[1000001],lv[1000001],que[1000001],l,r; 10 inline int Min(int p,int q){return p<q?p:q;} 11 void init(){ 12 int x; 13 scanf("%d%d",&n,&m); S=1, T=v(n,m); 14 F(i,1,n) F2(j,1,m) 15 scanf("%d",&x), ins(v(i,j),v(i,j+1),x); 16 F2(i,1,n) F(j,1,m) 17 scanf("%d",&x), ins(v(i,j),v(i+1,j),x); 18 F2(i,1,n) F2(j,1,m) 19 scanf("%d",&x), ins(v(i,j),v(i+1,j+1),x); 20 } 21 bool lvl(){ 22 memset(lv,0,sizeof lv); 23 lv[S]=1; que[1]=S; l=r=1; 24 int u; 25 while(l<=r){ 26 u=que[l++]; 27 for(int i=h[u];i;i=nxt[i]) 28 if(cap[i]&&!lv[to[i]]) lv[to[i]]=lv[u]+1, que[++r]=to[i]; 29 } if(!lv[T]) return 0; 30 F(i,S,T) iter[i]=h[i]; 31 return 1; 32 } 33 int flow(int u,int f){ 34 if(u==T) return f; 35 int d,sum=0; 36 for(int&i=iter[u];i;i=nxt[i]){ 37 if(cap[i]&&lv[to[i]]>lv[u]){ 38 d=flow(to[i],Min(cap[i],f)); 39 sum+=d; f-=d; 40 cap[i]-=d; cap[i^1]+=d; 41 if(!f) return sum; 42 } 43 } 44 return sum; 45 } 46 int Dinic(){ 47 int sum=0; 48 while(lvl()) 49 sum+=flow(S,999999999); 50 return sum; 51 } 52 int main(){ 53 init(); 54 printf("%d",Dinic()); 55 return 0; 56 }
?
轉載于:https://www.cnblogs.com/PinkRabbit/p/7327131.html
總結
以上是生活随笔為你收集整理的【bzoj题解】1001 狼抓兔子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Deepgreen数据库日志清理脚本
- 下一篇: 安卓投屏大师_玩转手机投屏,我推荐三款不