【POJ】2135 Farm Tour 最小费用最大流

来源:互联网 发布:jquery ajax 返回数据 编辑:程序博客网 时间:2024/06/07 08:24

题目传送门

这题用到了最小费用最大流,一条边的容量为1,代价为这条边的长度。

建立超级源点通向节点1,容量为2,代价为0;节点n通向超级汇点,容量为2,代价为0。

之后刷一遍最小费用最大流就行了。

注意:这题里的边都是双向边,比方说从节点x到节点y和从节点y到节点x是不同的走法。

附上AC代码:

#include <cstdio>#include <vector>#include <queue>#include <cstring>using namespace std;struct note{int from,to,w,v,nt;}side[100010];queue <int> que;int n,m,x,y,w,h[1010],dis[1010],f[1010],flow,cost,pre[1010],num,s,t;bool b[1010];void add(int x,int y,int w,int v){side[num]=(note){x,y,w,v,h[x]};h[x]=num++;side[num]=(note){y,x,0,-v,h[y]};h[y]=num++;}bool spfa(){for (int i=0; i<=t; ++i) dis[i]=1e9,b[i]=0;while (!que.empty()) que.pop();dis[s]=0,b[s]=1,f[s]=2e9,que.push(s);while (!que.empty()){int p=que.front();que.pop(),b[p]=0;for (int i=h[p]; ~i; i=side[i].nt)if (side[i].w&&dis[side[i].to]>dis[p]+side[i].v){dis[side[i].to]=dis[p]+side[i].v;pre[side[i].to]=i;f[side[i].to]=min(f[p],side[i].w);if (!b[side[i].to]){b[side[i].to]=1;que.push(side[i].to);}}}if (dis[t]==1e9) return 0;flow+=f[t];cost+=f[t]*dis[t];for (int i=t; i!=s; i=side[pre[i]].from){side[pre[i]].w-=f[n];side[pre[i]^1].w+=f[n];}return 1;}int main(void){scanf("%d%d",&n,&m),s=0,t=n+1;memset(h,-1,sizeof h);for (int i=1; i<=m; ++i){scanf("%d%d%d",&x,&y,&w);add(x,y,1,w),add(y,x,1,w);}add(s,1,2,0),add(n,t,2,0);while (spfa());printf("%d",cost);return 0;}

0 0
原创粉丝点击