zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    POJ 1887 Testing the CATCHER
    HDU 3374 String Problem
    HDU 2609 How many
    POJ 1509 Glass Beads
    POJ 1458 Common Subsequence
    POJ 1159 Palindrome
    POJ 1056 IMMEDIATE DECODABILITY
    POJ 3080 Blue Jeans
    POJ 1200 Crazy Search
    软件体系结构的艺术阅读笔记1
  • 原文地址:https://www.cnblogs.com/konjak/p/6049656.html
Copyright © 2011-2022 走看看