zoukankan      html  css  js  c++  java
  • [最小割]Cable TV Network UVA

    题目:求一个无向图的点联通数,n<=50

    思路:要删除一些点,让图不联通,关键是审视“不联通”这一概念。其实,不联通就是存在两个点没有路相连。可以考虑枚举两个点,问题就化简成了使两个点没有路。然而这个用最小割就很好做了,由于最小割模型是删除边的,所以把每个点拆成两点加一边,枚举的两个点分别为源点和汇点,跑最小割就行了。

    我想到最小割后就一直在想怎么判联通。。。还是too young了

    btw,大部分题解中只枚举一个点,这样做是不对的。比如说,你固定了源点,就默认了源点不能删,但恰好是删这个点最优呢?

    给出hack数据:

    3 2 (0,1) (0,2)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cassert>
     5 #include<queue>
     6 
     7 using namespace std;
     8 
     9 const int N=100+3,M=3000+3;
    10 const int INF=0x3f3f3f3f;
    11 
    12 struct edge{
    13     int nxt,to,fl;
    14 }ed[M];
    15 
    16 int head[N],cur;
    17 int s,t;
    18 queue<int>q;
    19 int cap[N],fr[N];
    20 
    21 void add_edge(int l,int r,int f)
    22 {
    23     ed[cur]=(edge){head[l],r,f};
    24     head[l]=cur++;
    25     ed[cur]=(edge){head[r],l,0};
    26     head[r]=cur++;
    27 }
    28 
    29 int n,m;
    30 int get;
    31 bool ek()
    32 {
    33     memset(cap,0,sizeof(cap));
    34     cap[s]=INF;
    35     while(!q.empty())q.pop();
    36     q.push(s);
    37     while(!q.empty())
    38     {
    39         int u=q.front();q.pop();
    40         for(int i=head[u];i!=-1;i=ed[i].nxt)
    41             if(!cap[ed[i].to]&&ed[i].fl)
    42                 cap[ed[i].to]=min(cap[u],ed[i].fl),
    43                 fr[ed[i].to]=i,
    44                 q.push(ed[i].to);
    45         if(cap[t])break;
    46     }
    47     if(!cap[t])return 0;
    48     get+=cap[t];
    49     for(int u=t;u!=s;u=ed[fr[u]^1].to)
    50         ed[fr[u]].fl-=cap[t],
    51         ed[fr[u]^1].fl+=cap[t];
    52     return 1;
    53 }
    54 
    55 
    56 
    57 int l[M],r[M];
    58 int main()
    59 {
    60     while(scanf("%d %d",&n,&m)!=EOF)
    61     {
    62         for(int i=1;i<=m;i++)
    63             scanf(" (%d,%d)",&l[i],&r[i]);
    64         int ans=n;
    65         for(s=0;s<n;s++)
    66             for(t=s+1;t<n;t++)
    67             {
    68                 memset(head,0xff,sizeof(head));
    69                 cur=0;
    70                 get=0;
    71                 for(int i=1;i<=m;i++)
    72                     add_edge(l[i],r[i]+n,n),
    73                     add_edge(r[i],l[i]+n,n);
    74                 for(int i=0;i<n;i++)
    75                     if(i==t||i==s)
    76                         add_edge(i+n,i,n);
    77                     else
    78                         add_edge(i+n,i,1);
    79                 while(ek());
    80                 ans=min(ans,get);
    81             }
    82         cout<<ans<<endl;
    83     }
    84     return 0;
    85 }[] 
  • 相关阅读:
    洛谷P2737 [USACO4.1]麦香牛块Beef McNuggets(DP,裴蜀定理)
    洛谷P4924 魔法少女小Scarlet
    洛谷P3912 素数个数
    洛谷P4016 负载平衡问题(费用流)
    洛谷P2736 [USACO3.4]“破锣摇滚”乐队 Raucous Rockers
    母函数(生成函数)
    洛谷P4086 [USACO17DEC]My Cow Ate My Homework S
    洛谷P5097 [USACO04OPEN]Cave Cows 2(ST表)
    洛谷P2713 罗马游戏(左偏树)
    洛谷P1260 工程规划
  • 原文地址:https://www.cnblogs.com/mgnfcnt/p/8728968.html
Copyright © 2011-2022 走看看