思路:求最短時間,可以想到二分,然後判斷可行性。首先在原圖上求 floyd,得到每兩個棚之間的最短距離。然後拆點:將每個棚拆為 i 和 i』(流進和流出),添邊(i,i』,inf)。增加源點 s 和匯點 t,從 s 連邊到 i,容量為該棚現在的貓的數量,i』連邊到 t,容量為該棚的容量。若棚 i 和棚 j 之間的距離不大於 limit,則連邊(i,j』,inf), (j,i』,inf)。求最大流,若從 s 發出的邊均滿流,則在 low 和 mid 中搜尋;否則在 mid 和 high 中搜尋。
1 #include2 #include3 #include4 #include5 #include6view codeusing
namespace
std;
7#define maxn 444
8#define maxm 44444444
9#define inf 1<<30
10#define inf 1ll<<60
1112
struct
edgeedge[maxm];
1516
intn,m,ne,vs,vt,nv;
17int
head[maxn];
1819
void insert(int u,int v,int
cap)
2031
32int
level[maxn],gap[maxn];
33void bfs(int
vt)3451}
52}53}
5455
intpre[maxn],cur[maxn];
56int sap(int vs,int
vt)57
79 aug=inf;80}
81break;82
}83}84
if(flag)continue;85
int minlevel=nv;
86for(int i=head[u];i!=-1;i=edge[i].next)92}
93if(--gap[level[u]]==0)break
;94 level[u]=minlevel+1
;95 gap[level[u]]++;
96 u=pre[u];97}
98return
maxflow;99}
100101
intnow_num[maxn],num[maxn];
102long
long
dist[maxn][maxn];
103void
floyd()
104111
112void build(long
long
limit)
113126
}127
}128
}129
130int
main()
131140
for(int i=1;i<=n;i++)
141for(int j=1;j<=n;j++)
142 dist[i][j]=(i==j)?0
:inf;
143while(m--)
149}
150floyd();
151 low=0,high=limit+1,mid,ans=-1
;152
while(low<=high)else
159 low=mid+1
;160
}161 printf("
%lld\n
",ans);
162}
163return0;
164 }
poj 2391 二分 最大流
思路 求最短時間,可以想到二分,然後判斷可行性。首先在原圖上求 floyd,得到每兩個棚之間的最短距離。然後拆點 將每個棚拆為 i 和 i 流進和流出 添邊 i,i inf 增加源點 s 和匯點 t,從 s 連邊到 i,容量為該棚現在的貓的數量,i 連邊到 t,容量為該棚的容量。若棚 i 和棚 j ...
POJ 2391 拆點 最大流 二分
題意就不再說了,主要是想說一下為啥要拆點 poj 2112跟本題很相似,也是二分,但它就沒用拆點,本題就用了 為啥呢?因為poj2112上建的圖中是乙個很明顯的二分圖,也就是左邊的點絕對不會跟左邊的點去連邊的。而本題中就不一樣了,任何點之間都可能有邊。會出現這種情況,1 2 3,這是一條鏈,而1 2...
poj 2112 最大流 二分
題意 有k臺擠奶機,c頭奶牛,給出這k c個實體間的距離,求出每頭奶牛都到一台擠奶機去,怎麼分配使奶牛走的最大距離最小。用二分列舉最大距離,include include define n 500 define inf 0x3fffffff int map n n dis n gap n head ...