poj 2135(最小费用最大流)

题目链接:http://poj.org/problem?id=2135

思路:把路长看作费用,然后如果u,v之间有边,就连u->v,v->u,边容量为1,表示每条边只能走一次,最后就是源点与1连边,容量为2,费用为0,n与汇点连边,容量为2,费用为0,表示增广2次。这样就转化为为最小费用最大流问题来求解了。

  1 #include<iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<queue>

  6 using namespace std;

  7 #define MAXN 1010

  8 #define MAXM 88888

  9 #define inf 1<<30

 10 

 11 struct Edge{

 12     int v,cap,cost,next;

 13 }edge[MAXM];

 14 

 15 int n,m,NE,vs,vt;

 16 int head[MAXN];

 17 

 18 void Insert(int u,int v,int cap,int cost)

 19 {

 20     edge[NE].v=v;

 21     edge[NE].cap=cap;

 22     edge[NE].cost=cost;

 23     edge[NE].next=head[u];

 24     head[u]=NE++;

 25 

 26     edge[NE].v=u;

 27     edge[NE].cap=0;

 28     edge[NE].cost=-cost;

 29     edge[NE].next=head[v];

 30     head[v]=NE++;

 31 }

 32 

 33 bool mark[MAXN];

 34 int dist[MAXN];

 35 int pre[MAXN],cur[MAXN];

 36 

 37 

 38 bool spfa(int vs,int vt)

 39 {

 40     memset(mark,false,sizeof(mark));

 41     fill(dist,dist+vt+1,inf);

 42     memset(pre,-1,sizeof(pre));

 43     queue<int>que;

 44     que.push(vs);

 45     mark[vs]=true;

 46     dist[vs]=0;

 47     while(!que.empty()){

 48         int u=que.front();

 49         que.pop();

 50         mark[u]=false;

 51         for(int i=head[u];i!=-1;i=edge[i].next){

 52             int v=edge[i].v,cost=edge[i].cost;

 53             if(edge[i].cap>0&&dist[u]+cost<dist[v]){

 54                 dist[v]=dist[u]+cost;

 55                 pre[v]=u;

 56                 cur[v]=i;

 57                 if(!mark[v]){

 58                     mark[v]=true;

 59                     que.push(v);

 60                 }

 61             }

 62         }

 63     }

 64     return dist[vt]<inf;

 65 }

 66 

 67 

 68 int MinCostFlow(int vs,int vt)

 69 {

 70     int cost=0,flow=0;

 71     while(spfa(vs,vt)){

 72         int aug=inf;

 73         for(int u=vt;u!=vs;u=pre[u]){

 74             aug=min(aug,edge[cur[u]].cap);

 75         }

 76         flow+=aug,cost+=dist[vt]*aug;

 77         for(int u=vt;u!=vs;u=pre[u]){

 78             edge[cur[u]].cap-=aug;

 79             edge[cur[u]^1].cap+=aug;

 80         }

 81     }

 82     return cost;

 83 }

 84 

 85 

 86 int main()

 87 {

 88     int u,v,cost;

 89     while(~scanf("%d%d",&n,&m)){

 90         NE=0;

 91         memset(head,-1,sizeof(head));

 92         vs=0,vt=n+1;

 93         while(m--){

 94             scanf("%d%d%d",&u,&v,&cost);

 95             Insert(u,v,1,cost);

 96             Insert(v,u,1,cost);

 97         }

 98         Insert(vs,1,2,0);

 99         Insert(n,vt,2,0);

100         int ans=MinCostFlow(vs,vt);

101         printf("%d\n",ans);

102     }

103     return 0;

104 }
View Code

 

 

你可能感兴趣的:(poj)