• 2017青岛赛区网络赛 Smallest Minimum Cut 求最小割的最小割边数


    先最大流跑一遍

    在残存网络上把满流边容量+1

    非满流边容量设为无穷大

    在进行一次最大流即可

    (这里的边都不包括建图时用于反悔的反向边)

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<queue>
      5 #include<iostream>
      6 #define rep(i,a,b) for(int i=a;i<=b;++i)
      7 using namespace std;
      8 const int MAXN=210;
      9 int tmp,m,n,S,T,Ans;
     10 int tot=0,ans=0,Maxflow=0;
     11 int h[MAXN];
     12 int pointer[MAXN];
     13 int a[MAXN],path[MAXN];
     14 const int INF=~0U>>1;
     15 struct Edge{
     16     int next,to;
     17     int cap,op;                 //op指向反向边 cap为容量 f为流量
     18     int f;
     19     Edge() {};
     20     Edge(int b,int c,int nxt,int num,int flow) {to=b,cap=c,next=nxt,op=num^1,f=flow;}
     21 }edge[MAXN*10];
     22 void addedge(int a,int b,int c)  //a到b容量为c
     23 {
     24     edge[tot]=Edge(b,c,pointer[a],tot,0);
     25     pointer[a]=tot++;
     26     edge[tot]=Edge(a,0,pointer[b],tot,0);                     //建立b到a的反向边
     27     pointer[b]=tot++;
     28 }
     29 void Input()
     30 {
     31     memset(pointer,-1,sizeof(pointer));
     32     Maxflow=0,tot=0;
     33     scanf("%d%d",&n,&m);
     34     scanf("%d%d",&S,&T);
     35     int u,v,w;
     36     rep(i,1,m)
     37     {
     38         scanf("%d%d%d",&u,&v,&w);
     39         addedge(u,v,w);
     40     }
     41 }
     42 bool Dinic_restruct()          //bfs建立层次图
     43 {
     44     queue <int>q;
     45     memset(h,-1,sizeof(h));
     46     h[S]=0;q.push(S);
     47     while(!q.empty())
     48     {
     49         int u=q.front();q.pop();
     50         for(int i=pointer[u];i!=-1;i=edge[i].next)
     51         {
     52             int v=edge[i].to;
     53             if(h[v]==-1&&edge[i].cap-edge[i].f)
     54             {
     55                 h[v]=h[u]+1;
     56                 q.push(v);
     57              //   printf("v=%d T=%d u=%d
    ",v,T,u);
     58                 if(v==T) return true;
     59             }
     60         }
     61     }
     62     return false;
     63 }
     64 void Dinic_augment()     //dfs找最短增光路
     65 {
     66     int i,j,f,Stop=1;
     67     a[Stop]=S;
     68     while(Stop)
     69     {
     70         i=a[Stop];
     71      //   printf("augment i=%d
    ",i);
     72         if(i!=T)       //没到T就走一步,dfs
     73         {
     74             int v;
     75             for(j=pointer[i];j!=-1;j=edge[j].next)
     76                 {
     77                     v=edge[j].to;
     78                     if(h[v]==h[i]+1&&edge[j].cap-edge[j].f) break;
     79                 }
     80             if(j!=-1)
     81             {
     82                 a[++Stop]=v;
     83                 path[Stop]=j;
     84             }
     85             else            //回退
     86             {
     87 
     88                 Stop--;
     89                 h[i]=-1;
     90                // printf("-1 augment i=%d
    ",i);
     91             }
     92         }
     93         else    //找到了一条完整的路径
     94         {
     95             f=INF;
     96             for(i=Stop;i>=2;i--)
     97             {
     98                 int &t=path[i];
     99                 if(edge[t].cap-edge[t].f<f)
    100                     f=edge[t].cap-edge[t].f;
    101             }
    102             Maxflow+=f;
    103             for(int i=Stop;i>=2;i--)
    104             {
    105                 int &t=path[i];
    106                 edge[t].f+=f;
    107                 edge[t^1].f-=f;    //反向边
    108                 if(edge[t].cap-edge[t].f==0) Stop=i-1;
    109             }
    110         }
    111     }
    112 }
    113 void Dinic()
    114 {
    115     while(Dinic_restruct())
    116         Dinic_augment();
    117 
    118 }
    119 int main()
    120 {
    121  //   freopen("in.txt","r",stdin);
    122     int T;
    123     scanf("%d",&T);
    124     rep(t1,1,T)
    125     {
    126         Input();
    127         Dinic();
    128        // printf("ok? Maxflow=%d
    ",Maxflow);
    129         for(int i=0;i<tot;i+=2)
    130         {
    131            // printf("i=%d to=%d  w=%d
    ",i,edge[i].to,edge[i].cap-edge[i].f);
    132             if((edge[i].cap-edge[i].f)==0)
    133             {
    134                 edge[i].cap+=1;
    135             }
    136             else
    137             {
    138                 edge[i].cap=INF;
    139             }
    140         }
    141         Maxflow=0;
    142         Dinic();
    143         printf("%d
    ",Maxflow);
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    .net NEST7.17.0 ES客户端帮助类
    .net5 根据类型注入所有的继承关系
    ANSI控制码 cmd echo设置字体、背景色、前景色
    windows racketmq部署
    c# 运行时判断是否为DEBUG模式
    .net minio 帮助类 minio4.0.1
    获取解决方案中所有的程序集
    spoonweb保存400问题解决
    关于kettle环境初始化 KettleEnvironment.init() 报错的解决
    PythonMutableDict使用范例
  • 原文地址:https://www.cnblogs.com/zhixingr/p/7618068.html
Copyright © 2020-2023  润新知