poj 2391 二分 最大流

2021-09-06 11:41:12 字數 1925 閱讀 7122

思路:求最短時間,可以想到二分,然後判斷可行性。首先在原圖上求 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 #include6

using

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 }

view code

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 ...