POJ 2391 拆點 最大流 二分

2021-08-27 02:33:33 字數 2194 閱讀 3315

題意就不再說了,主要是想說一下為啥要拆點

poj 2112跟本題很相似,也是二分,但它就沒用拆點,本題就用了

為啥呢? 因為poj2112上建的圖中是乙個很明顯的二分圖,也就是左邊的點絕對不會跟左邊的點去連邊的。而本題中就不一樣了,任何點之間都可能有邊。

會出現這種情況,1->2->3,這是一條鏈,而1->2最短路為1,2->3為1,1->3為 2,此時如果我們限制最大距離為1的話,建的新圖中必然有1->2,2-3, 然後我們就發現問題了,新圖中1和3也會間接的連線起來,而我們顯然是不想這麼讓它流的。這就需要拆點了,對每個點x,拆成x'和x'',然後x'和x''之間有一條無限容量的邊,這樣的話,隨便多少牛路過這個點都是可以的,如果i->j這條邊符合了距離限制,就加i'->j'' 所有的邊加完後,建立源點,對所有的x'連邊,容量為已經有的牛,匯點的話,就用所有的j''連線匯點,容量就是能容納的牛的數量。

這樣一拆點,就發現之前的問題不復存在了,還是比如1->2->3這個例子,加的邊是1』->2'',2'->3'' 不會有流從1流到3去,因為加的每條邊都流向了匯點

#include #include #include #include #include #include #include #include #include #define maxn 555

#define maxm 222222

#define inf 1000000007

using namespace std;

struct node

edge[maxm];

int dist[maxn], numbs[maxn], src, des, n;

int head[maxn], e;

void add(int x, int y, int c)

void rev_bfs()

q[qtail++] = des;

dist[des] = 0;

numbs[0] = 1;

while(qhead != qtail)

}}void init()

int maxflow()

totalflow += augflow;

u = src;

}int i;

for(i = curhead[u]; i != -1; i = edge[i].next)

if(edge[i].cap > 0 && dist[u] == dist[edge[i].ver] + 1)break;

if(i != -1) // find an admissible arc, then advance

else // no admissible arc, then relabel this vertex

}return totalflow;

}int f, p;

int now[maxn], can[maxn];

long long d[maxn][maxn];

void floyd(int n)

int main()

for(int i = 1; i <= f; i++)

for(int j = 1; j <= f; j++)

if(i != j) d[i][j] = 2000000000000ll;

else d[i][j] = 0;

int u, v, w;

for(int i = 1; i <= p; i++)

floyd(f);

long long low = 0, high = 0;

for(int i = 1; i <= f; i++)

for(int j = 1; j <= f; j++)

if(d[i][j] != 2000000000000ll) high = max(high, d[i][j]);

n = 2 * f + 2;

src = 1;

des = n;

long long ans = -1;

while(low <= high)

rev_bfs();

int flow = maxflow();

//printf("dsfsd %d\n", flow);

if(flow == total)

else low = mid + 1;

}printf("%lld\n", ans);

return 0;

}

poj 2391 二分 最大流

思路 求最短時間,可以想到二分,然後判斷可行性。首先在原圖上求 floyd,得到每兩個棚之間的最短距離。然後拆點 將每個棚拆為 i 和 i 流進和流出 添邊 i,i inf 增加源點 s 和匯點 t,從 s 連邊到 i,容量為該棚現在的貓的數量,i 連邊到 t,容量為該棚的容量。若棚 i 和棚 j ...

poj 2391 二分 最大流

思路 求最短時間,可以想到二分,然後判斷可行性。首先在原圖上求 floyd,得到每兩個棚之間的最短距離。然後拆點 將每個棚拆為 i 和 i 流進和流出 添邊 i,i inf 增加源點 s 和匯點 t,從 s 連邊到 i,容量為該棚現在的貓的數量,i 連邊到 t,容量為該棚的容量。若棚 i 和棚 j ...

POJ 3498 拆點 最大流

大概題意 在南極的海洋上,有一些企鵝站在一些浮冰上,這些企鵝想聚在一塊,也就是到某塊浮冰上聚會,但是它們不想游泳,只想從一塊浮冰跳到另一塊上,自身的跳躍距離題中已經給出來了,然後是每個浮冰的座標,該浮冰上已經有個多少個企鵝,以及浮冰的承受能力,所謂承受能力不是指能載動多少企鵝,題目中說了每個浮冰載企...