• 【uva 1658】Admiral(图论--网络流 最小费用最大流)


    题意:有个N个点M个边的有向加权图,求1~N的两条不相交路径(除了起点和终点外没有公共点),使得权和最小。

    解法:不相交?也就是一个点只能经过一次,也就是我后面博文会讲的“结点容量问题”。(呃不,写完这博文几天后的今天,我负责任地 m(._.)m 告诉大家,我不会写这博文了......我的时间不多了......          m(_ _;;m 大家可以看蓝书。)常用方法就是拆点法,把一个点拆成两个点,中间连一条容量为1、费用为0的边。于是求1到 n 的流量为2的最小费用流就可以了。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<queue>
     6 using namespace std;
     7 
     8 const int N=1010,M=10010,NN=2010,MM=22000,D=110,INF=(int)1e9;
     9 int n,m,len;
    10 int last[NN],d[NN],vis[NN],flow[NN];
    11 int pre[NN],id[NN];
    12 struct edge{int x,y,fl,c,next;}e[MM];
    13 queue<int> q;
    14 
    15 int mmin(int x,int y) {return x<y?x:y;}
    16 void ins(int x,int y,int fl,int c)
    17 {
    18     e[++len].x=x,e[len].y=y,e[len].fl=fl,e[len].c=c;
    19     e[len].next=last[x],last[x]=len;
    20     e[++len].x=y,e[len].y=x,e[len].fl=0,e[len].c=-c;
    21     e[len].next=last[y],last[y]=len;
    22 }
    23 bool spfa(int st,int ed)
    24 {
    25     while (!q.empty()) q.pop();
    26     memset(d,63,sizeof(d));//>1e9
    27     memset(vis,0,sizeof(vis));
    28     memset(pre,0,sizeof(pre));
    29     q.push(st);
    30     d[st]=0,vis[st]=1,flow[st]=INF;
    31     while (!q.empty())
    32     {
    33       int x=q.front(); q.pop(); 
    34       vis[x]=0;//spfa
    35       for (int i=last[x];i;i=e[i].next)
    36       {
    37         int y=e[i].y;
    38         if (d[x]+e[i].c<d[y] && e[i].fl)
    39         {
    40           d[y]=d[x]+e[i].c;
    41           flow[y]=mmin(flow[x],e[i].fl);
    42           pre[y]=x, id[y]=i;
    43           if (!vis[y]) q.push(y),vis[y]=1;
    44         }
    45       }
    46     }
    47     return pre[ed];
    48 }
    49 int Max_flow(int st,int ed)
    50 {
    51     int sum=0;
    52     while (spfa(st,ed))
    53     {
    54       sum+=flow[ed]*d[ed];
    55       for (int i=ed;i!=st;i=pre[i])
    56       {
    57         e[id[i]].fl-=flow[ed];
    58         e[id[i]^1].fl+=flow[ed];
    59       }
    60     }
    61     return sum;
    62 }
    63 int main()
    64 {
    65     while (scanf("%d%d",&n,&m)!=EOF)
    66     {
    67       int x,y,z; len=1;
    68       memset(last,0,sizeof(last));
    69       for (int i=2;i<n;i++) ins(i,n+i-1,1,0);
    70       ins(n,2*n-1,2,0);
    71 //拆点就是真的拆点不能ins(i,i...)  n+1~2n-2
    72       for (int i=1;i<=m;i++)
    73       {
    74         scanf("%d%d%d",&x,&y,&z);
    75         if (x!=1) x=n+x-1;//只有1没有拆多一个点
    76         ins(x,y,1,z);
    77       }
    78       //for (int i=2;i<=len;i++)
    79       //  printf("%d %d %d %d %d
    ",e[i].x,e[i].y,e[i].fl,e[i].c,e[i].next);
    80       int ans=Max_flow(1,2*n-1);
    81       printf("%d
    ",ans);
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    网络编程中 TCP 半开连接和TIME_WAIT 学习
    redis中的小秘密和持久化小细节
    排序
    Es官方文档整理-3.Doc Values和FieldData
    Es官方文档整理-2.分片内部原理
    Elasticsearch doc_value认识
    路边停靠 贴边停车不蹭轮胎的技巧
    mybatis 连接数据库
    putIfAbsent
    Hive与HBase区别 大墨垂杨
  • 原文地址:https://www.cnblogs.com/konjak/p/6049656.html
Copyright © 2020-2023  润新知