1. 程式人生 > >POJ - 2391 最大流

POJ - 2391 最大流

數組越界 target printf struct ble image 今天 type 代碼檢查

題目鏈接:http://poj.org/problem?id=2391

今天掉坑多次。

做了幾道題,發現從源點出來的邊和進入匯點的邊都在題目中出來過。

POJ真是坑,交G++一直wa,檢查代碼檢查了好幾遍,無望看discuss,才知道交C++是RE,才知道數組越界了。

手寫了Floyd,寫成 i,j,k,wa了,突然想到以前遇到過這種問題。

技術分享

看昂神解釋明白了。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5
#include <iostream> 6 #include <queue> 7 using namespace std; 8 #define next Next 9 const int inf = 0x3f3f3f3f; 10 const int maxn=500; 11 int level[maxn]; 12 int iter[maxn]; 13 int head[maxn],tot; 14 struct edge{ 15 int to,cap,Next; 16 } e[80805]; ///此處應為邊的兩倍,加一條容量為0的反向邊 17 void
init(){ 18 memset(head,-1,sizeof(head)); 19 tot=0; 20 } 21 void add(int from,int to,int cap){ 22 e[tot].Next=head[from]; 23 e[tot].to=to; 24 e[tot].cap=cap; 25 head[from]=tot; 26 tot++; 27 } 28 void addedge(int from,int to,int cap){ 29 add(from,to,cap); 30 add(to,from
,0); 31 } 32 void bfs(int s){ 33 memset(level,-1,sizeof(level)); 34 queue<int> q; 35 level[s]=0; 36 q.push(s); 37 while(!q.empty()){ 38 int v=q.front(); q.pop(); 39 for(int i=head[v];~i;i=e[i].Next){ 40 edge &ed=e[i]; 41 if(ed.cap>0&&level[ed.to]<0){ 42 level[ed.to]=level[v]+1; 43 q.push(ed.to); 44 } 45 } 46 } 47 } 48 int dfs(int v,int t,int f){ 49 if(v==t) return f; 50 for(int &i=iter[v];~i;i=e[i].Next){ 51 edge &ed=e[i]; 52 if(ed.cap>0&&level[v]<level[ed.to]){ 53 int d=dfs(ed.to,t,min(f,ed.cap)); 54 if(d>0){ 55 ed.cap-=d; 56 e[i^1].cap+=d; 57 return d; 58 } 59 } 60 } 61 return 0; 62 } 63 int max_flow(int s,int t){ 64 int flow=0; 65 while(1){ 66 bfs(s); 67 if(level[t]<0) return flow; 68 memcpy(iter,head,sizeof(iter)); 69 int f; 70 while((f=dfs(s,t,inf))>0){ 71 flow+=f; 72 } 73 } 74 } 75 int niu[maxn],capacity[maxn]; 76 typedef long long ll; 77 ll dp[maxn][maxn]; 78 void floyd(int n) 79 { 80 for(int k=1;k<=n;k++) 81 { 82 for(int i=1;i<=n;i++) 83 { 84 //if(i==j) continue; 85 for(int j=1;j<=n;j++) 86 { 87 if(i==k||j==k||i==j) continue; 88 dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]); 89 } 90 } 91 } 92 } 93 int f,p; 94 void cons(ll T,int s,int t) 95 { 96 init(); 97 for(int i=1;i<=f;i++) 98 { 99 addedge(s,i,niu[i]); 100 addedge(i,i+f,inf); 101 addedge(i+f,t,capacity[i]); 102 } 103 for(int i=1;i<=f;i++) 104 { 105 for(int j=1;j<=f;j++) 106 { 107 if(i==j) continue; 108 if(dp[i][j]<=T) 109 { 110 addedge(i,j+f,inf); 111 } 112 } 113 } 114 } 115 int main() 116 { 117 int sum = 0; 118 scanf("%d %d",&f,&p); 119 for(int i=1;i<=f;i++) 120 { 121 scanf("%d %d",&niu[i],&capacity[i]); 122 sum += niu[i]; 123 } 124 for(int i=1;i<=f;i++) 125 { 126 for(int j=1;j<=f;j++) 127 { 128 dp[i][j] = 1e15; 129 } 130 } 131 for(int i=1;i<=p;i++) 132 { 133 int x,y; 134 ll w; 135 scanf("%d %d %lld",&x,&y,&w); 136 dp[x][y] = min(dp[x][y],w); ///一定要註意兩點之間的有多條邊的情況 137 dp[y][x] = dp[x][y]; 138 } 139 floyd(f); 140 ll l = 0,r = 2000000000000LL; 141 ll mid = 0; 142 int s,t; 143 s = 420,t = 421; ///s,t一定要在head數組範圍內 144 int flow = 0; 145 ll ans = 0; 146 while(l<=r) 147 { 148 mid = (l+r)/2LL; 149 cons(mid,s,t); 150 flow = max_flow(s,t); 151 // printf("%lld %d\n",mid,flow); 152 if(flow==sum) 153 { 154 ans = mid; 155 r = mid-1; 156 } 157 else 158 { 159 l = mid+1; 160 } 161 } 162 if(ans==0) 163 { 164 puts("-1"); 165 } 166 else 167 { 168 printf("%lld\n",ans); 169 } 170 return 0; 171 } 172 /* 173 3 4 174 7 2 175 0 4 176 2 6 177 1 2 40 178 1 2 70 179 1 2 90 180 1 2 120 181 */

POJ - 2391 最大流