• bzoj 2561: 最小生成树


     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define M 100009
     5 #define inf 2139062143
     6 using namespace std;
     7 int n,m,S,tot,cnt=1,T,ans,head[20005],d[20005],q[2*M],next[10*M],u[10*M],v[10*M],a[3*M][3];
     8 bool bfs()
     9 {
    10     memset(d,0,sizeof(d));
    11     int h=0,t=1;
    12     q[1]=S;
    13     d[S]=1;
    14     for(;h<t;)
    15       {
    16         h++;
    17         int p=q[h];
    18         for(int i=head[p];i;i=next[i])
    19           if(!d[u[i]]&&v[i])
    20             {
    21                 d[u[i]]=d[p]+1;
    22                 if(d[T])
    23                   return 1;
    24                 t++;
    25                 q[t]=u[i];
    26             }
    27       }
    28     return 0;
    29 }
    30 int dinic(int s,int f)
    31 {
    32     if(s==T)
    33       return f;
    34     int rest=f;
    35     for(int i=head[s];i&&rest;i=next[i])
    36       if(v[i]&&d[u[i]]==d[s]+1)
    37         {
    38             int now=dinic(u[i],min(rest,v[i]));
    39             if(!now)
    40               d[u[i]]=0;
    41             v[i]-=now;
    42             v[i^1]+=now;
    43             rest-=now;
    44         }
    45     return f-rest;  
    46 }
    47 void jia1(int a1,int a2,int a3)
    48 {
    49     cnt++;
    50     next[cnt]=head[a1];
    51     head[a1]=cnt;
    52     u[cnt]=a2;
    53     v[cnt]=a3;
    54     return;
    55 }
    56 void jia(int a1,int a2,int a3)
    57 {
    58     jia1(a1,a2,a3);
    59     jia1(a2,a1,0);
    60     return;
    61 }
    62 int main()
    63 {
    64     int s;
    65     scanf("%d%d",&n,&m);
    66     for(int i=1;i<=m;i++)
    67       scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
    68     scanf("%d%d%d",&S,&T,&s);
    69     cnt=1;
    70     memset(head,0,sizeof(head));
    71     for(int i=1;i<=m;i++)
    72       if(a[i][2]>s)
    73         {
    74            jia(a[i][0],a[i][1],1);
    75            jia(a[i][1],a[i][0],1);
    76         }
    77     for(;bfs();)
    78       ans+=dinic(S,inf);
    79     cnt=1;
    80     memset(head,0,sizeof(head));
    81     for(int i=1;i<=m;i++)
    82       if(a[i][2]<s)
    83         {
    84           jia(a[i][0],a[i][1],1);
    85           jia(a[i][1],a[i][0],1);
    86         }
    87     for(;bfs();)
    88       ans+=dinic(S,inf);
    89     printf("%d
    ",ans);
    90     return 0;
    91 }

    两遍网络流,把比他小的边建起来,最大流就是要删的边数,最大生成树同理。

  • 相关阅读:
    HDUOJ---Can you solve this equation?
    HDUOJ---A + B Again
    C++知识整理(进制)
    位运算的方法,大结
    位运算的方法,小结
    C++知识整理(在此感谢大牛的整理)
    nyoj---快速查找素数
    HDUOJ----湫湫系列故事——减肥记I
    《道德经》:十条简洁有用的人生建议
    Nginx的几个常用配置和技巧
  • 原文地址:https://www.cnblogs.com/xydddd/p/5304337.html
Copyright © 2020-2023  润新知