zoukankan      html  css  js  c++  java
  • UVA 1658 Admiral 海上将军(最小费用流,拆点)

    题意:

      一个有v个点的有向图,要从点1到点v需要找两条路径,两路径不可经过同一个点(除了1和v点)。求这两条路径的最小费用(保证有解)。

    分析:

      难在建图,其他套模板。

      此图给的是超级复杂图,两个点之间有多条有向边,方向还可能是相反的。用网络流来做不能仅靠2点流来保证,因为当只有3个点,4条边都是1->2->3这样的,是不是刚好2条路径?也满足了2点流的限制。其实不能这样,要保证经过每个点1点流量,还得拆点,将2~v-1这些点都拆两个点,两点之间有条费用为0容量为1的边,这样就能保证了。然后源点1出发,汇点v结束,都是流量为2就行了。当然源点,汇点需要自己另外建。

      1 #include <bits/stdc++.h>
      2 #define LL long long
      3 #define pii pair<int,int>
      4 #define INF 0x7f7f7f7f
      5 using namespace std;
      6 const int N=2000+50;
      7 
      8 struct node
      9 {
     10     int from;
     11     int to;
     12     int val;
     13     int cap;
     14     int flow;
     15 }edge[N*N];
     16 int edge_cnt, ans_cost;
     17 int flow[N], cost[N], path[N], inq[N];
     18 
     19 vector<int> vect[N];
     20 
     21 void add_node(int from,int to,int val,int cap,int flow)
     22 {
     23     edge[edge_cnt].from=from;
     24     edge[edge_cnt].to=to;
     25     edge[edge_cnt].val=val;
     26     edge[edge_cnt].cap=cap;
     27     edge[edge_cnt].flow=flow;
     28     vect[from].push_back(edge_cnt++);
     29 }
     30 
     31 
     32 int spfa(int s,int e)
     33 {
     34     deque<int> que(1,s);
     35     inq[s]=1;
     36     cost[s]=0;
     37     flow[s]=INF;
     38 
     39     while(!que.empty())
     40     {
     41         int x=que.front();
     42         que.pop_front();
     43         inq[x]=0;
     44         for(int i=0; i<vect[x].size(); i++)
     45         {
     46             node e=edge[vect[x][i]];
     47             if(e.cap>e.flow && cost[e.to]>cost[e.from]+e.val)
     48             {
     49                 flow[e.to]=min(flow[e.from],e.cap-e.flow);
     50                 cost[e.to]=cost[e.from]+e.val;
     51                 path[e.to]=vect[x][i];
     52                 if(!inq[e.to])
     53                 {
     54                     inq[e.to]=1;
     55                     que.push_back(e.to);
     56                 }
     57             }
     58         }
     59     }
     60     return flow[e];
     61 }
     62 
     63 
     64 int cal(int s,int e)
     65 {
     66     int ans_flow=0;
     67     while(true)
     68     {
     69         memset(flow, 0, sizeof(flow));
     70         memset(path, 0, sizeof(path));
     71         memset(cost, 0x7f, sizeof(cost));
     72         memset(inq, 0, sizeof(inq));
     73 
     74         int tmp=spfa(s, e);
     75         if(!tmp)    return ans_cost;
     76         ans_cost+=cost[e];
     77         ans_flow+=tmp;
     78 
     79         int ed=e;
     80         while(ed!=s)
     81         {
     82             int t=path[ed];
     83             edge[t].flow+=tmp;
     84             edge[t^1].flow-=tmp;
     85             ed=edge[t].from;
     86         }
     87     }
     88 }
     89 
     90 
     91 int main()
     92 {
     93     freopen("input.txt", "r", stdin);
     94     int n, m, a, b, c;
     95     while(~scanf("%d%d",&n,&m))
     96     {
     97         ans_cost=0;
     98         edge_cnt=0;
     99         for(int i=n+1; i>=0; i-- )    vect[i].clear();
    100         memset(edge,0,sizeof(edge));
    101         for(int i=2; i<n; i++)
    102         {
    103             add_node(i*2,i*2+1,0,1,0);
    104             add_node(i*2+1,i*2,0,0,0);
    105         }
    106         for(int i=0; i<m; i++)
    107         {
    108             scanf("%d%d%d", &a, &b, &c);
    109             add_node(a*2+1, b*2, c, 1, 0);
    110             add_node(b*2, a*2+1, -c, 0, 0);
    111         }
    112 
    113         add_node(2, 2*1+1, 0, 2, 0);  //源点。2点流量
    114         add_node(2*1+1, 2, 0, 0, 0);
    115 
    116         add_node(n*2, n*2+1, 0, 2, 0);//汇点
    117         add_node(n*2+1, n*2, 0, 0, 0);
    118 
    119         printf("%d
    ",cal(2, n*2+1));
    120     }
    121     return 0;
    122 }
    AC代码
  • 相关阅读:
    Web开发框架 SSH 简介
    H5 性能调优 工具
    Mongodb性能调优
    峰Redis学习(4)Redis 数据结构(List的操作)
    峰Redis学习(3)Redis 数据结构(字符串、哈希)
    峰Redis学习(2)Jedis 入门实例
    峰Redis学习(1)Redis简介和安装
    使用jquery.mCustomScrollbar自定义滚动条(2)
    使用jquery.mCustomScrollbar自定义滚动条(1)
    jquery zTree异步搜索的例子--搜全部节点
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4646748.html
Copyright © 2011-2022 走看看