POJ 3422 最大費用 cpp

2022-05-14 10:54:04 字數 1905 閱讀 7780

題意:

給出乙個每一格帶值的矩陣

每一次只可以從左上角走到右下角

問走過k次後最多能得到多少值

p.s 走過的格仔值會變成0

輸入:給出乙個n 和 k

給出n*n 矩陣

思路:

因為求的是最大值

所以應該求最長距離..把最小路徑改成求最大路徑

《相應改變的就是鬆弛操作 和 dis的初始狀態》

為了保證每個點只取一次值 並且 可以經過多次

就進行拆點 然後對應點之間加兩條邊 ①. 容量為1 費用為該點的值 ②. 容量為inf 費用為0

①邊保證了該點走過後變為0值 ②邊保證該點可以經過多次

還有超級源點跟每個點之間連邊 容量為k 費用為0

超級匯點和每個拆點之間連邊 容量為k 費用為0

tips:

加邊的時候記得判斷邊界情況..

還有因為拆點了 和 加了超級源點和匯點  邊數就要相應增多..

迴圈佇列也要開大點..  

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 = 6000;8

const

int maxm = 100010;9

struct

edge

10edge[maxm];

17int

head[maxn];

18int

tot;

19int

n, k;

20int

dis[maxn], pre[maxn];

21bool

flag[maxn];

2223

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

f)24

3940

int que[maxn*100

];41

bool spfa(int s, int

e)4263}

64}65}

6667

if(dis[e] == -1)68

return

false;69

else

return

true;70

}7172int min_c_f(int s, int

e)73

84 u =pre[e];

85while(u != -1

) 90 ans_c += dis[e]*mn;

91 ans_f +=mn;92}

93return

ans_c;94}

9596

intmain()

97115

116 add(0, 1, 0

, k);

117 add(2*t, 2*t+1, 0

, k);

118int ans = min_c_f(0, 2*t+1

);119 printf("

%d\n

", ans);

120}

121return0;

122 }

poj3422 最小費用最大流

記得以前做過這樣類似的題,因為那時候求的是來回的最大值,直接使用的dp,而且對費用流並不是很清楚,然後又看到了這道題。對點進行拆分建圖,乙個點拆為兩個點a和b,在a和b之間建一條花費為輸入值容量為1的邊,然後再建一條花費為0容量為k 1的邊,對b點對於其右邊和下邊都建立一條容量為k花費為0的邊,加入...

POJ 3422 最大流最小費用

題目大意 給定一張網格圖,需要從 1,1 走到 n,n 走k條路,每次走到乙個格仔上會把它的值變為0並且加到sum上去,問sum的最大值是多少 題目解析 構圖考慮到走一次費用就變成了0,所以乙個點要拆成2的點兩個點之間有一條邊容量為1,另一條容量為k 1,費用為0 因為是最大費用,只要把所有的值變成...

poj 3422 最小費用最大流

思路 求從起點到終點走k次獲得的最大值,最小費用最大流的應用 將點權轉化為邊權,需要拆點,邊容量為1,費用為該點的點權,表示該點的權值只能獲取一次,另外,應該連一條容量為inf,費用為0的邊,因為每條邊都可以走多次。另外就是增加源點和匯點了,源點與起點連容量為k,費用為0的邊,表示可以走k次,同理終...