POJ2135 Farm Tour 最小费用流

给出一个图,从一号节点去N号节点,再回来。

但是不能经过相同的边,即一条边最多只能够走一次。

求来回的总长度的最小值。

转化:

求1号到N号的2条没有公共边的路径,这样就相当于在这个图中所有边的容量都是1,现在要找2条增广路,得到的流量为2,就相当于求流量为2的最小费用流。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<vector>
  5 
  6 using namespace std;
  7 
  8 const int maxn=1005;
  9 const int inf=0x3f3f3f3f;
 10 const int s=1;
 11 int t;
 12 
 13 inline int min(int x,int y)
 14 {
 15     return x<y?x:y;
 16 }
 17 
 18 struct Edge
 19 {
 20     int to,cap,cost,rev;
 21 };
 22 vector<Edge>edge[maxn];
 23 int prev[maxn];
 24 int pree[maxn];
 25 int dist[maxn];
 26 int vis[maxn];
 27 
 28 void addedge(int from,int to,int cap,int cost)
 29 {
 30     edge[from].push_back((Edge){to,cap,cost,edge[to].size()});
 31     edge[to].push_back((Edge){from,0,-cost,edge[from].size()-1});
 32 }
 33 
 34 void build_graph(int n,int m)
 35 {
 36     t=n;
 37     for(int i=1;i<=m;i++)
 38     {
 39         int u,v,w;
 40         scanf("%d%d%d",&u,&v,&w);
 41         addedge(u,v,1,w);
 42         addedge(v,u,1,w);
 43     }
 44 }
 45 
 46 void spfa(int n)
 47 {
 48     memset(vis,false,sizeof vis);
 49     for(int i=2;i<=n;i++)
 50         dist[i]=inf;
 51     dist[1]=0;
 52     queue<int>que;
 53     while(!que.empty())
 54         que.pop();
 55     que.push(s);
 56     vis[s]=true;
 57     while(!que.empty())
 58     {
 59         int u=que.front();
 60         que.pop();
 61         vis[u]=false;
 62         for(int i=0;i<edge[u].size();i++)
 63         {
 64             Edge &e=edge[u][i];
 65             if(e.cap>0&&dist[e.to]>dist[u]+e.cost)
 66             {
 67                 dist[e.to]=dist[u]+e.cost;
 68                 prev[e.to]=u;
 69                 pree[e.to]=i;
 70                 if(!vis[e.to])
 71                 {
 72                     que.push(e.to);
 73                     vis[e.to]=true;
 74                 }
 75             }
 76         }
 77     }
 78 }
 79 
 80 int min_cost_flow(int f,int n)
 81 {
 82     int ret=0;
 83     while(f>0)
 84     {
 85         spfa(n);
 86         int d=f;
 87         for(int v=t;v!=s;v=prev[v])
 88         {
 89             d=min(d,edge[prev[v]][pree[v]].cap);
 90         }
 91         f-=d;
 92         ret+=dist[t]*d;
 93         for(int v=t;v!=s;v=prev[v])
 94         {
 95             Edge &e=edge[prev[v]][pree[v]];
 96             e.cap-=d;
 97             edge[e.to][e.rev].cap+=d;
 98         }
 99     }
100     return ret;
101 }
102 
103 int main()
104 {
105     int n,m;
106     while(~scanf("%d%d",&n,&m))
107     {
108         build_graph(n,m);
109 
110         printf("%d
",min_cost_flow(2,n));
111     }
112     return 0;
113 }
View Code
原文地址:https://www.cnblogs.com/-maybe/p/4694306.html