zoukankan      html  css  js  c++  java
  • POJ 1966 去掉最少的点使得图不连通(最小点割)

    题目链接: http://poj.org/problem?id=1966

    题目大意:

      给定一个无向图,求最少去掉多少个点后使得原图不连通(至少分成2不部分)。  

    分析:

      题意也即: 对任意两个不相邻的点,求他们之间的独立轨数P( a, b )。最后是 min( P( a, b ) )就是整个图的连通度。这题在网络流题目分类里的题解说是固定任意源点,枚举汇点求最小的点割,后来又看了Discuss里的一句话,说是源点也要枚举,因为有可能任意选的源点属于最小点割集。

      那么由于之前做过一个最小点割的,也就是点要进行拆点化成边割来求,点i拆成 i 和 i+n,之间连容量为1的边,如果i和j相连,因为考虑到是无向边,所以i+n向j连一条容量为无穷大的边,同时j+n向i连一条容量为无穷大的边。

      注意最后如果定 ST 为超级源点,那么边< ST, ST+n >的容量需要赋为无穷大。

      最后对每个枚举到的源汇点对,从超级源点ST向超级汇点ED跑一次最大流,取最小值既是答案,注意如果最后的答案是无穷大,那么所以该图是一个双连通分量,应该输出点数n。

      另外一个很好的总结包括有向图,无向图,混合图的最小点割。http://blog.csdn.net/zhuyingqingfen/article/details/6386268

    (P.S.  这题的输入说会有多个空格,所以我开始一直错在输入方式的处理上,最后看了网上的代码用了 scanf(" (%d,%d)", &x, &y) 才过的,具体见代码,值得收藏)

    代码:

    poj1966
     1 /*1966    Accepted    300K    63MS    C++    2366B    2012-06-14 22:09:21*/
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <vector>
     8 using namespace std;
     9 
    10 #define mpair make_pair
    11 #define pii pair<int,int>
    12 #define MM(a,b) memset(a,b,sizeof(a));
    13 typedef long long lld;
    14 typedef unsigned long long u64;
    15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
    16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
    17 #define maxn 110
    18 const int inf= 2100000000;
    19 
    20 int n,m, ST=0, ED, NV;
    21 int map[maxn][maxn];
    22 int g[maxn][maxn];
    23 
    24 int pre[maxn], que[maxn];
    25 bool vis[maxn];
    26 bool bfs(){
    27     MM( vis, 0 );
    28     int head= 0, tail= 0;
    29     que[tail++]= ST;
    30     vis[ST]= 1;
    31     while( head<tail ){
    32         int u= que[head++];
    33         for(int v=0;v<NV;++v){
    34             if( g[u][v]>0 && !vis[v] ){
    35                 pre[v]= u;
    36                 if( v==ED ) return 1;
    37                 que[tail++]= v;
    38                 vis[v]= 1;
    39             }
    40         }
    41     }
    42     return 0;
    43 }
    44 
    45 int Edmond_karp(){
    46     int ret= 0;
    47     while( bfs() ){
    48         int t= inf;
    49         for(int i=ED;i!=ST;i=pre[i]){
    50             up_min( t, g[pre[i]][i] );
    51         }
    52         ret+= t;
    53         for(int i=ED;i!=ST;i=pre[i]){
    54             g[pre[i]][i]-= t;
    55             g[i][pre[i]]+= t;
    56         }
    57     }
    58     return ret;
    59 }
    60 
    61 int main()
    62 {
    63     //freopen("poj1966.in","r",stdin);
    64     while( cin>>n>>m ){
    65         NV= n+n;
    66         MM( map, 0 );
    67         for(int i=0;i<n;++i) map[i][i+n]= 1;
    68         /*while( ch= getchar(), ch!='\n' ){  /// Wrong!!!
    69             if( ch == '(' ){
    70                 int x,y;
    71                 scanf("%d,%d", &x, &y);
    72                 map[x+n][y]= inf;
    73                 map[y+n][x]= inf;
    74             }
    75         }*/
    76         while(m--){
    77             int x,y;
    78             scanf(" (%d,%d)", &x, &y); /// my god;~!!!
    79             map[x+n][y]= inf;
    80             map[y+n][x]= inf;  ///!!!
    81         }
    82         if( n<2 ){ printf("%d\n", n); continue; }
    83 
    84         int ans= inf;
    85         for(ST=0; ST<n; ++ST){
    86             for(ED=ST+1; ED<n; ++ED){
    87                 for(int k=0;k<NV;++k)for(int k1=0;k1<NV;++k1)g[k][k1]= map[k][k1];
    88                 g[ST][ST+n]= inf;
    89                 int t= Edmond_karp();
    90                 up_min( ans, t );
    91             }
    92         }
    93         if( ans==inf ) ans= n;
    94         cout<< ans <<endl;
    95     }
    96 }

     

     

    一毛原创作品,转载请注明出处。
  • 相关阅读:
    Linq之Lambda表达式初步认识
    Linq之Expression高级篇(常用表达式类型)
    nginx: [emerg] bind() to 0.0.0.0:443 failed(98:Address already in use)解决方法
    ubuntu18.04如何查看,关闭,激活虚拟机的防火墙
    Dictionary 不区分大小写
    Zookeeper 3、Zookeeper工作原理(详细)
    查看Navicat已保存数据库密码
    is not allowed to connect to this mysql server
    error while loading shared libraries: libstdc++.so.6: cannot open shared obj
    [转]Linux网络配置命令ifconfig输出信息解析
  • 原文地址:https://www.cnblogs.com/yimao/p/2549920.html
Copyright © 2011-2022 走看看