POJ 2135 最小費用最大流 cpp

2022-05-14 10:54:06 字數 1950 閱讀 9916

題意:

給出m個路徑的起點和終點還有長度

找出一條路徑可以從1到n然後回到1..

並保證找到的路徑是不重複而且是最短的..

思路:

容量控制經過只有1次

費用控制長度

在建完圖後求最小費用最大流..

就可以找出最短距離..而且沒有重複路徑..

tips:

※ 0點作為超級源點和1相連   n+1作為超級匯點和n相連    然後容量為2費用為0 保證一進一出

※ 建圖的時候..相鄰的正反邊要緊挨著寫..

因為更改圖中的容量的時候..

edge[load[u]].c -= mn;

edge[load[u]^1].c += mn;

位運算表示的是反向邊..所以加的時候應該緊挨著加..

※ 加邊的時候..除了加已知的邊 還要加入反向邊 同時要加入容量為0 費用為負值的邊..

所以每次運算的時候..應該先加入一條正向邊 然後加入正向邊的反向負值邊

然後加入一條反向邊 再加入反向邊的反向負值邊

code:

view code

1 #include 2 #include 3 #include 4

using

namespace

std;

5#define clr(x) memset(x, 0, sizeof(x))

6const

int inf = 0x1f1f1f1f;7

const

int maxn = 1010;8

const

int maxm = 100010;9

struct

edge

10edge[maxm];

16int

head[maxn];

17int

tot;

18int

n;19

intdis[maxn], load[maxn], p[maxn];

20bool

flag[maxn];

2122

void add(int s, int u, int c, int

f)23

3031

bool spfa(int s, int

en)3256}

57}58}

59}60if(dis[en] ==inf)

61return

false;62

else

return

true;63

}6465int min_c_f(int s, int

e)66

77 u =e;

78while(p[u] != -1

) 83 ans_f += dis[e]*mn;

84 ans_c +=mn;85}

86return

ans_f;87}

8889

intmain()

90107

108 add(0, 1, 2, 0

);109 add(1, 0, 2, 0

);110 add(n, n + 1, 2, 0

);111 add(n+1, n , 2, 0

);112

int ans = min_c_f(0, n+1

);113 printf("

%d\n

", ans);

114}

115return0;

116 }

poj 2135 最小費用最大流

題意是正向走一次反向走一次,每條路只能走一次,問走最少距離是多少。解題方法 每條路流量為1,費用為距離,建立乙個超級源與超級匯流量為2,費用為0,將超級源連線至點1上,超級匯連線至點n上,這樣求1次最大流就能出來正反兩次走法了,就不用反圖去找了。因為為無向圖,所以每條路建兩次邊,正向一次反向一次。i...

poj 2135 最小費用最大流

題意 給定乙個無向圖,要從1點到n點再返回1點,每條邊最多走一次,問最短需要走多遠。分析 最小費用最大流,把題意看成是要找兩條無交集的從1到n的路線,使距離和最小。圖中的點和邊就是網路流圖中的點和邊。設定乙個源,接到1點,設定乙個匯,從n點接到匯。為保證無交集,我們把每條邊的流量設定為1,而源發出的...

poj 2135 最小費用最大流

思路 把路長看作費用,然後如果u,v之間有邊,就連u v,v u,邊容量為1,表示每條邊只能走一次,最後就是源點與1連邊,容量為2,費用為0,n與匯點連邊,容量為2,費用為0,表示增廣2次。這樣就轉化為為最小費用最大流問題來求解了。1 include2 include3 include4 inclu...