您的位置:首页 > 其它

poj2135 最小费用最大流模板

2016-05-02 11:23 260 查看
点击打开链接
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>

using namespace std;
#define V 10010
#define E 100010
#define inf 0x3f3f3f3f

struct Edge{
int x,y,next,cap,cost;
}edge[E];

int pre[V],dist[V],head[V],vis[V];
int cnt = 0;

void init()
{
cnt = 0;
memset(head,-1,sizeof(head));
}

void addedge(int u,int v,int c,int cost)
{
edge[cnt].x=u;edge[cnt].y=v;edge[cnt].cost=cost;
edge[cnt].cap=c;edge[cnt].next=head[u];head[u]=cnt++;

edge[cnt].x=v;edge[cnt].y=u;edge[cnt].cost=-cost;
edge[cnt].cap=0;edge[cnt].next=head[v];head[v]=cnt++;//注意反向边cap为0!!WA好几次...
}
int spfa(int start,int end)
{
queue<int>q;
for(int i=0;i<=end+2;i++){
dist[i]=inf,vis[i]=0,pre[i]=-1;
}
vis[start]=1,dist[start]=0;
q.push(start);
while(!q.empty())
{
int now=q.front();
q.pop();
int u,v;
u=now;
vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
if(edge[i].cap>0)
{
v=edge[i].y;
if(dist[v]>dist[u]+edge[i].cost)
{
dist[v]=dist[u]+edge[i].cost;
pre[v]=i;//记录前驱
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
}
return dist[end]!=inf;
}

int MCMF(int begin,int end)
{
int ans=0,flow,flow_sum=0;
while(spfa(begin,end))
{
flow=inf;
for(int i=pre[end];i!=-1;i=pre[edge[i].x])flow=min(flow,edge[i].cap);
//cout<<flow<<endl;
for(int i=pre[end];i!=-1;i=pre[edge[i].x]){
edge[i].cap-=flow;
edge[i^1].cap+=flow;//i^1就变成反边了?高大上...
}
flow_sum+=flow;
ans+=dist[end];//这题最大流只有1或0,一般化的是flow*dist[end];
}
return ans;
}

int main()
{
//freopen("in.txt","r",stdin);
int n,m,a,b,c;
while(scanf("%d%d",&n,&m)!=EOF){
init();
addedge(0,1,2,0);
addedge(n,n+1,2,0);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,1,c);
addedge(b,a,1,c);
}
printf("%d\n",MCMF(0,n+1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: