当前位置: 代码迷 >> 综合 >> poj-3422-Kaka's Matrix Travels-最小费用最大流
  详细解决方案

poj-3422-Kaka's Matrix Travels-最小费用最大流

热度:77   发布时间:2023-12-19 10:54:48.0

最小费用最大流。

建图方式如图所示


然后就是费用流的模板~~

把最小费用转化成最大费用,做法一样。

还有一种做法,就是把所有的边的费用取负,然后去最小费用,然后去负值就好。‘

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define INF 99999999
#define maxn 5050
#define LL long long
struct list
{int l;int r;int v;int f;int next;
}node[1000001];
int num;
int head[1000001];
int pre[maxn];
int n,k;
int st,ed;
LL ans;
int ns;
void add(int l,int r,int v,int f)
{node[num].l=l;node[num].r=r;node[num].v=v;node[num].f=f;node[num].next=head[l];head[l]=num++;node[num].l=r;node[num].r=l;node[num].v=-v;node[num].f=0;node[num].next=head[r];head[r]=num++;
}
int bfs()
{int visit[maxn];int dist[maxn];int i;for(i=0;i<=ns;i++)dist[i]=-1;memset(visit,0,sizeof(visit));memset(pre,-1,sizeof(pre));queue<int >q;q.push(0);dist[0]=0;visit[0]=1;while(!q.empty()){int e=q.front();q.pop();visit[e]=0;for(i=head[e];i!=-1;i=node[i].next){int r=node[i].r;if(dist[r]<dist[e]+node[i].v&&node[i].f>0){pre[r]=i;dist[r]=dist[e]+node[i].v;if(!visit[r]){q.push(r);visit[r]=1;}}}}if(dist[ns]==-1)return 0;return 1;
}
void change()
{int minx,i;minx=INF;for(i=pre[ns];node[i].l!=0;i=pre[node[i].l]){minx=min(minx,node[i].f);}for(i=pre[ns];node[i].l!=0;i=pre[node[i].l]){node[i].f-=minx;node[i^1].f+=minx;ans+=minx*node[i].v;}
}
int main()
{int i,j;int ll,rr;while(~scanf("%d%d",&n,&k)){memset(head,-1,sizeof(head));num=0;int a;for(i=1;i<=n;i++){for(j=1;j<=n;j++){scanf("%d",&a);ll=(i-1)*n+j;rr=ll+n*n;add(ll,rr,a,1);add(ll,rr,0,k-1);if(j<n){ll=(i-1)*n+j+n*n;rr=(i-1)*n+j+1;add(ll,rr,0,k);}if(i<n){ll=(i-1)*n+j+n*n;rr=i*n+j;add(ll,rr,0,k);}}}ll=n*n+n*n;rr=ll+1;ns=rr;ans=0;add(0,1,0,k);add(ll,rr,0,k);while(bfs())change();cout<<ans<<endl;}return 0;
}


  相关解决方案