zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    堆栈
    一元多项式的乘法和加法
    单链表每隔k反转
    python命令行参数
    markdown学习笔记
    ansible学习笔记
    Linux进程管理和性能相关工具
    二分查找,折半查找,特殊情况二分查找
    插入排序,冒泡排序,归并排序, 稳定排序
    不稳定排序,选择排序,快速排序,快速排序优化, 内部排序
  • 原文地址:https://www.cnblogs.com/-maybe/p/4694306.html
Copyright © 2011-2022 走看看