[luogu 2045 方格取数加强版][poj 3422] Kaka's Matrix Travels {最大费用最大流,Edmonds-Karp算法}

版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/89000089

题目

http://poj.org/problem?id=3422


解题思路

先拆点,然后两边,最后跑费用流的模板。 O K ! ! ! OK!!!

最长路。

bool spfa(){
	queue<int> q; 
	memset(d,0xcf,sizeof(d)); 
	memset(v,0,sizeof(v)); 
	q.push(s); d[s]=0; v[s]=1; 
	incf[s]=1<<30; 
	while(q.size()){
		int x=q.front(); v[x]=0; q.pop(); 
		for (int i=head[x];i;i=a[i].next){
			if (a[i].z==0) continue; 
			int y=a[i].y; 
			if (d[y]<d[x]+a[i].c)  {
				d[y]=d[x]+a[i].c; 
				incf[y]=min(incf[x],a[i].z); 
				pre[y]=i; 
				if (!v[y]) v[y]=1,q.push(y); 
			}
		}
	}
	return (d[t]==0xcfcfcfcf)?0:1; 
}
void update(){
	int x=t; 
	while (x!=s) {
		int i=pre[x]; 
		a[i].z-=incf[t]; a[i^1].z+=incf[t]; x=a[i^1].y; 
	}
	maxflow+=incf[t],ans+=d[t]*incf[t]; 
}

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define rep(i,x,y) for (register int i=x;i<=y;i++)
using namespace std; 
const int N=5010,M=200010; 
struct node{int y,z,c,next;}a[M];
int d[N],incf[N],pre[N],v[N],head[N]; 
int n,k,tot=1,s,t,maxflow,ans; 
void add(int x,int y,int z,int c){
	a[++tot]=(node){y,z,c,head[x]}; head[x]=tot; 
	a[++tot]=(node){x,0,-c,head[y]}; head[y]=tot; 
}
int num(int i,int j,int k){return (i-1)*n+j+k*n*n;}
bool spfa(){
	queue<int> q; 
	memset(d,0xcf,sizeof(d)); 
	memset(v,0,sizeof(v)); 
	q.push(s); d[s]=0; v[s]=1; 
	incf[s]=1<<30; 
	while(q.size()){
		int x=q.front(); v[x]=0; q.pop(); 
		for (int i=head[x];i;i=a[i].next){
			if (a[i].z==0) continue; 
			int y=a[i].y; 
			if (d[y]<d[x]+a[i].c)  {
				d[y]=d[x]+a[i].c; 
				incf[y]=min(incf[x],a[i].z); 
				pre[y]=i; 
				if (!v[y]) v[y]=1,q.push(y); 
			}
		}
	}
	return (d[t]==0xcfcfcfcf)?0:1; 
}
void update(){
	int x=t; 
	while (x!=s) {
		int i=pre[x]; 
		a[i].z-=incf[t]; a[i^1].z+=incf[t]; x=a[i^1].y; 
	}
	maxflow+=incf[t],ans+=d[t]*incf[t]; 
}
int main(){
	scanf("%d%d",&n,&k); 
	s=1,t=2*n*n;
	rep(i,1,n) rep(j,1,n){
		int c; scanf("%d",&c); 
		add(num(i,j,0),num(i,j,1),1,c); 
		add(num(i,j,0),num(i,j,1),k-1,0); 
		if (j<n) add(num(i,j,1),num(i,j+1,0),k,0); 
		if (i<n) add(num(i,j,1),num(i+1,j,0),k,0); 
	}
	while (spfa()) update(); printf("%d",ans); 
}

猜你喜欢

转载自blog.csdn.net/qq_39897867/article/details/89000089