• 【uva 1349】Optimal Bus Route Design(图论--网络流 二分图的最小权完美匹配)


    题意:有一个N个点的有向带权图,要求找若干个有向圈,使得每个点恰好属于一个圈。请输出满足以上条件的最小权和。

    解法:有向圈?也就是每个点有唯一的后继。这是一个可逆命题,同样地,只要每个点都有唯一的后继,那么它们一定恰好属于一个圈。而“唯一”可以想到二分图匹配。把每个点拆成两个点,分别放在二分图的两边。两侧的点连的边就是原来的边的转化,另外再给源点和汇点分别连 n 条容量为1、费用为0的边。这样就保证了每个点有唯一的后继。再由于是要求所有点都属于一个圈,也就是完美匹配,就判断一下是否满流,流入汇点的总流量是否为 n 就行了。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<queue>
     6 using namespace std;
     7 
     8 const int N=110,M=30010,NN=310,D=110,INF=(int)1e9;
     9 int n,len;
    10 int last[NN],vis[NN],id[NN],pre[NN],flow[NN],d[NN];
    11 struct edge{int y,fl,c,next;}e[M];
    12 queue<int> q;
    13 
    14 int mmin(int x,int y) {return x<y?x:y;}
    15 void ins(int x,int y,int fl,int c)
    16 {
    17     e[++len].y=y,e[len].fl=fl,e[len].c=c;
    18     e[len].next=last[x],last[x]=len;
    19     e[++len].y=x,e[len].fl=0,e[len].c=-c;
    20     e[len].next=last[y],last[y]=len;
    21 }
    22 bool spfa(int st,int ed)
    23 {
    24     while (!q.empty()) q.pop();
    25     memset(vis,0,sizeof(vis));
    26     memset(d,63,sizeof(d));
    27     memset(pre,0,sizeof(pre));
    28     q.push(st);
    29     d[st]=0,vis[st]=1,flow[st]=INF;
    30     while (!q.empty())
    31     {
    32       int x=q.front();
    33       q.pop(); vis[x]=0;
    34       for (int i=last[x];i;i=e[i].next)
    35       {
    36         int y=e[i].y;
    37         if (e[i].fl && d[x]+e[i].c<d[y])
    38         {
    39           d[y]=d[x]+e[i].c;
    40           flow[y]=mmin(flow[x],e[i].fl);
    41           id[y]=i,pre[y]=x;
    42           if (!vis[y]) q.push(y),vis[y]=1;
    43         }
    44       }
    45     }
    46     return pre[ed];
    47 }
    48 int Max_flow(int st,int ed)
    49 {
    50     int sum=0,h=0;
    51     while (spfa(st,ed))
    52     {
    53       sum+=flow[ed]*d[ed];
    54       h+=flow[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     if (h==n) return sum;
    62     return 0;
    63 }
    64 int main()
    65 {
    66     while (1)
    67     {
    68       scanf("%d",&n);
    69       if (!n) break;
    70       int st=2*n+1,ed=2*n+2,x,y;
    71       len=1;
    72       memset(last,0,sizeof(last));
    73       for (int i=1;i<=n;i++)
    74       {
    75         ins(st,i,1,0),ins(n+i,ed,1,0);
    76         while (1)
    77         {
    78           scanf("%d",&x);
    79           if (!x) break;
    80           scanf("%d",&y);
    81           ins(i,n+x,1,y);
    82         }
    83       }
    84       int ans=Max_flow(st,ed);
    85       if (!ans) printf("N
    ");
    86       else printf("%d
    ",ans);
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    XML(学习笔记)
    css样式学习笔记
    Request(对象)
    sql一些错误修改的总结
    转载(如何学习C#)
    sql server(学习笔记2 W3Cschool)
    sql sqrver(学习笔记1 W3Cschool)
    关于 flutter开发碰到的各种问题,有的已经解决有的一直没解决或者用其他方法替代
    关于 Flutter IOS build It appears that your application still contains the default signing identifier.
    关于 flutter本地化问题 The getter 'pasteButtonLabel' was called on null
  • 原文地址:https://www.cnblogs.com/konjak/p/6049884.html
Copyright © 2020-2023  润新知