日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【BZOJ - 1001】狼抓兔子(无向图网络流,最小割,或平面图转对偶图求最短路SPFA)

發(fā)布時間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【BZOJ - 1001】狼抓兔子(无向图网络流,最小割,或平面图转对偶图求最短路SPFA) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題干:

現(xiàn)在小朋友們最喜歡的"喜羊羊與灰太狼",話說灰太狼抓羊不到,但抓兔子還是比較在行的,

而且現(xiàn)在的兔子還比較笨,它們只有兩個窩,現(xiàn)在你做為狼王,面對下面這樣一個網(wǎng)格的地形:

?

左上角點為(1,1),右下角點為(N,M)(上圖中N=4,M=5).有以下三種類型的道路?

1:(x,y)<==>(x+1,y)?

2:(x,y)<==>(x,y+1)?

3:(x,y)<==>(x+1,y+1)?

道路上的權(quán)值表示這條路上最多能夠通過的兔子數(shù),道路是無向的. 左上角和右下角為兔子的兩個窩,

開始時所有的兔子都聚集在左上角(1,1)的窩里,現(xiàn)在它們要跑到右下解(N,M)的窩中去,狼王開始伏擊

這些兔子.當然為了保險起見,如果一條道路上最多通過的兔子數(shù)為K,狼王需要安排同樣數(shù)量的K只狼,

才能完全封鎖這條道路,你需要幫助狼王安排一個伏擊方案,使得在將兔子一網(wǎng)打盡的前提下,參與的

狼的數(shù)量要最小。因為狼還要去找喜羊羊麻煩.

Input

第一行為N,M.表示網(wǎng)格的大小,N,M均小于等于1000.

接下來分三部分

第一部分共N行,每行M-1個數(shù),表示橫向道路的權(quán)值.?

第二部分共N-1行,每行M個數(shù),表示縱向道路的權(quán)值.?

第三部分共N-1行,每行M-1個數(shù),表示斜向道路的權(quán)值.?

輸入文件保證不超過10M

Output

輸出一個整數(shù),表示參與伏擊的狼的最小數(shù)量.

Sample Input

3 4 5 6 4 4 3 1 7 5 3 5 6 7 8 8 7 6 5 5 5 5 6 6 6

Sample Output

14

Hint

?

?2015.4.16新加數(shù)據(jù)一組,可能會卡掉從前可以過的程序。

?

解題報告:

? ?首先題干有誤,這顯然是不對的、、、不過還好樣例是正確的。。

然后,對于無向圖求最小割,加反邊直接把板子的反邊流量0也改成w就可以了。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long using namespace std; const int MAXN = 1005000; const int MAXM = 6005000; const int INF = 0x3f3f3f3f; struct Edge {int to,next,cap,flow; } edge[MAXM]; int tol; int head[MAXN]; void init() {tol = 2;memset(head, -1,sizeof(head)); } void addedge(int u,int v,int w,int rw = 0) {edge[tol].to = v;edge[tol].cap = w;edge[tol].flow = 0;edge[tol].next = head[u];head[u] = tol++;edge[tol].to = u;edge[tol].cap = rw;edge[tol].flow = 0;edge[tol].next = head[v];head[v] = tol++; } int Q[MAXN]; int dep[MAXN],cur[MAXN],sta[MAXN]; bool bfs(int s,int t,int n) {int front = 0,tail = 0;memset(dep,-1,sizeof(dep[0])*(n+1));dep[s] = 0;Q[tail++] = s;while(front < tail) {int u = Q[front++];for(int i = head[u]; i != -1; i = edge[i].next) {int v = edge[i].to;if(edge[i].cap > edge[i].flow && dep[v] == -1) {dep[v] = dep[u] + 1;if(v == t)return true;Q[tail++] = v;}}}return false; } int dinic(int s,int t,int n) {int maxflow = 0;while(bfs(s,t,n)) {for(int i = 1; i <= n; i++)cur[i] = head[i];int u = s, tail = 0;while(cur[s] != -1) {if(u == t) {int tp = INF;for(int i = tail-1; i >= 0; i-- )tp = min(tp,edge[sta[i]].cap - edge[sta[i]].flow);maxflow += tp;for(int i = tail-1; i >= 0; i-- ) {edge[sta[i]].flow += tp;edge[sta[i]^1].flow -= tp;if(edge[sta[i]].cap - edge[sta[i]].flow == 0)tail = i;}u = edge[sta[tail]^1].to;} else if(cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to]) {sta[tail++] = cur[u];u = edge[cur[u]].to;} else {while(u != s && cur[u] == - 1)u = edge[sta[--tail]^1].to;cur[u] = edge[cur[u]].next;}}}return maxflow; } int n,m; int id(int i,int j) {return (i-1)*m+j; } int main() {while(~scanf("%d%d",&n,&m)) {init();int st=1,ed=n*m;for(int w,i = 1; i<=n; i++) {for(int j = 1; j<=m-1; j++) {scanf("%d",&w);addedge(id(i,j),id(i,j+1),w,w);}}for(int w,i = 1; i<=n-1; i++) {for(int j = 1; j<=m; j++) {scanf("%d",&w);addedge(id(i,j),id(i+1,j),w,w);}}for(int w,i = 1; i<=n-1; i++) {for(int j = 1; j<=m-1; j++) {scanf("%d",&w);addedge(id(i,j),id(i+1,j+1),w,w);}}printf("%d\n",dinic(st,ed,n*m));} return 0 ; }

這題還可以強行轉(zhuǎn)化成最短路問題:

https://www.cnblogs.com/reddest/p/5954756.html

也就是把他看成一個平面圖然后轉(zhuǎn)化成對偶圖,這樣轉(zhuǎn)化成一個最短路問題,但是建圖還是有一定難度。具體參考博客。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的【BZOJ - 1001】狼抓兔子(无向图网络流,最小割,或平面图转对偶图求最短路SPFA)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。