題意:
給出乙個每一格帶值的矩陣
每一次只可以從左上角走到右下角
問走過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 4using
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次,同理終...