poj3422 最小費用最大流

2021-06-18 21:23:55 字數 1613 閱讀 1991

記得以前做過這樣類似的題,因為那時候求的是來回的最大值,直接使用的dp,而且對費用流並不是很清楚,然後又看到了這道題。。。

對點進行拆分建圖,乙個點拆為兩個點a和b,在a和b之間建一條花費為輸入值容量為1的邊,然後再建一條花費為0容量為k-1的邊,對b點對於其右邊和下邊都建立一條容量為k花費為0的邊,加入超級源點和匯點,花費為0容量為k,由此套模板就可以了!

下面是**:

/// file name: 2195.cpp

// author: wang

// mail: [email protected]

// created time: 2013/10/25 19:28:26

/#include #include #include #include #include #include #include#include#include using namespace std;

typedef long long ll;

#define inf (int_max/10)

#define sqr(x) ((x)*(x))

#define rep(i, n) for (int i=0; i<(n); ++i)

#define repf(i, a, b) for (int i=(a); i<=(b); ++i)

#define repd(i, a, b) for (int i=(a); i>=(b); --i)

#define clr(ar,val) memset(ar, val, sizeof(ar))

#define inf 100000000

#define n 5010

class match;

node a[n*1000];

int dis[n];

bool vis[n];

int point[n];

int len,pre[n];

void init()

void addpage(int x,int y,int cap,int cost)

bool spfa()}}

} if(dis[t]!=inf) return true;

else return false;

} int fond()

}return -ans;

}};match sa;

int a[55][55];

int n,m;

int main()

{ while(scanf("%d%d",&n,&m)!=eof)

{ repf(i,1,n)

repf(j,1,n)

scanf("%d",&a[i][j]);

sa.init();

sa.s=0; sa.t=2*n*n+1;

repf(i,1,n)

repf(j,1,n)

{int k=(i-1)*n+j;//2*k,2*k-1

sa.addpage(2*k-1,2*k,1,-a[i][j]);

sa.addpage(2*k,2*k-1,0,a[i][j]);

sa.addpage(2*k-1,2*k,m-1,0);

sa.addpage(2*k,2*k-1,0,0);

if(i

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次,同理終...

POJ 3422 最小費用最大流

關鍵是如何處理 只能獲取一次 的問題,為此可以為每個點建立偽點,由兩條有向邊相連。原始點到偽點連一條容量為1,權值為負分數的邊 原始點到偽點連一條容量為無窮,權值為0的邊。前者表示分數只能拿一次,後者表示第二次第三次 可以繼續走這個點,但是不拿分數。負權是因為題目要求的是 最大費用 又因為最多走同乙...