記得以前做過這樣類似的題,因為那時候求的是來回的最大值,直接使用的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的邊。前者表示分數只能拿一次,後者表示第二次第三次 可以繼續走這個點,但是不拿分數。負權是因為題目要求的是 最大費用 又因為最多走同乙...