首页 > 代码库 > [POJ 2135]Farm Tour(最小费用最大流)
[POJ 2135]Farm Tour(最小费用最大流)
蒟蒻zyk又来发水题题解了。。。
题目链接:http://poj.org/problem?id=2135
题意:无向边的最小费用最大流,注意要另建超级源点和超级汇点,加一条无向边相当于加4条有向边。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <queue> #define MAXV 10100 #define MAXE 1000100 #define INF 0x3f3f3f3f using namespace std; struct edge { int u,v,w,cap,next; }edges[MAXE]; int n,m; int head[MAXV],nCount=-1; int last[MAXV],dist[MAXV]; bool inQueue[MAXV]; void AddEdge(int U,int V,int W,int C) { //正向边 edges[++nCount].u=U; edges[nCount].v=V; edges[nCount].w=W; edges[nCount].cap=C; edges[nCount].next=head[U]; head[U]=nCount; //反向边 edges[++nCount].u=V; edges[nCount].v=U; edges[nCount].w=-W; edges[nCount].cap=0; edges[nCount].next=head[V]; head[V]=nCount; } bool SPFA(int s,int t) { queue<int>q; memset(last,-1,sizeof(last)); memset(dist,INF,sizeof(dist)); memset(inQueue,false,sizeof(inQueue)); inQueue[s]=true; dist[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); inQueue[u]=false; for(int p=head[u];p!=-1;p=edges[p].next) { if(edges[p].cap>0) { int v=edges[p].v; if(dist[u]+edges[p].w<dist[v]) { dist[v]=dist[u]+edges[p].w; last[v]=p; if(!inQueue[v]) { inQueue[v]=true; q.push(v); } } } } } return dist[t]<INF; } int MCMF(int s,int t) //求s到t的最小费用最大流 { int sumcost=0,sumflow=0,flow; while(SPFA(s,t)) { flow=INF; for(int i=last[t];i!=-1;i=last[edges[i].u]) { if(edges[i].cap<flow) flow=edges[i].cap; } for(int i=last[t];i!=-1;i=last[edges[i].u]) { edges[i].cap-=flow; //正向边减去容量 edges[i^1].cap+=flow; //反向边加容量 } sumcost+=dist[t]; sumflow+=flow; } return sumcost; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); AddEdge(0,1,0,2); //建立超级源点 AddEdge(n,n+1,0,2); //建立超级汇点 for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); AddEdge(u,v,w,1); AddEdge(v,u,w,1); } printf("%d\n",MCMF(0,n+1)); } return 0; }
[POJ 2135]Farm Tour(最小费用最大流)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。