zoukankan      html  css  js  c++  java
  • POJ 1966 无向图点联通度 最小割

    题意:

    给定一个无向图,求最少去掉多少个点后使得原图不连通(即存在两点不连通)。

    题解:

    暴力枚举起点终点,做最小割~取最小的即可

    特判一些极端情况,比如m=0等等~

    连通度总结(复习用~,转自 : http://blog.csdn.net/zhuyingqingfen/article/details/6386268 ):

    图的连通度问题是指:在图中删去部分元素(点或边),使得图中指定的两个点s和t不连通
    (不存在从s到t的路径),求至少要删去几个元素。
    图的连通度分为点连通度和边连通度:
    (1)点连通度:只许删点,求至少要删掉几个点(当然,s和t不能删去,这里保证原图中至少有三个点);
    (2)边连通度:只许删边,求至少要删掉几条边。
    并且,有向图和无向图的连通度求法不同,因此还要分开考虑(对于混合图,只需将其中所有的无向边按照
    无向图的办法处理、有向边按照有向图的办法处理即可)。
    【1】有向图的边连通度:
    这个其实就是最小割问题。以s为源点,t为汇点建立网络,原图中的每条边在网络中仍存在,容量为1,
    求该网络的最小割(也就是最大流)的值即为原图的边连通度。
    【2】有向图的点连通度:
    需要拆点。建立一个网络,原图中的每个点i在网络中拆成i'与i'',有一条边<i', i''>,容量为1
    (<s', s''>和<t', t''>例外,容量为正无穷)。原图中的每条边<i, j>在网络中为边<i'', j'>,
    容量为正无穷。以s'为源点、t''为汇点求最大流,最大流的值即为原图的点连通度。
    说明:最大流对应的是最小割。显然,容量为正无穷的边不可能通过最小割,也就是原图中的边和s、t两个点
    不能删去;若边<i, i''>通过最小割,则表示将原图中的点i删去。
    【3】无向图的边连通度:
    将图中的每条边(i, j)拆成<i, j>和<j, i>两条边,再按照有向图的办法(【1】)处理;
    【4】无向图的点连通度:
    将图中的每条边(i, j)拆成<i, j>和<j, i>两条边,再按照有向图的办法(【2】)处理。

    View Code
      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <algorithm>
      6 
      7 #define N 500
      8 #define M 50000
      9 #define INF 1e9
     10 
     11 using namespace std;
     12 //必须暴力枚举起点和终点,因为 固定的起点可能就是割点 
     13 int head[N],to[M],next[M],len[M];
     14 int q[M*4],layer[N];
     15 bool map[N][N];
     16 int n,m,S,T,cnt,sn;
     17 
     18 inline void add(int u,int v,int w)
     19 {
     20     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
     21     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;
     22 }
     23 
     24 inline void read()
     25 {
     26     memset(map,0,sizeof map);
     27     sn=n<<1;
     28     int a,b;
     29     while(m--)
     30     {
     31         scanf(" (%d,%d)",&a,&b);
     32         a++,b++;
     33         map[a][b]=map[b][a]=true;
     34     }
     35 }
     36 
     37 inline void build()
     38 {
     39     memset(head,-1,sizeof head); cnt=0;
     40     for(int i=1;i<=n;i++)
     41         for(int j=1;j<=n;j++)
     42             if(map[i][j]) add(i,j+n,INF);
     43     for(int i=1;i<=n;i++)
     44     {
     45         if(i==S||i==T) add(i,i+n,INF),add(i+n,i,INF);
     46         else add(i,i+n,1),add(i+n,i,1);
     47     }
     48 }
     49 
     50 inline bool bfs()
     51 {
     52     memset(layer,-1,sizeof layer);
     53     int h=1,t=2,sta;
     54     q[1]=S; layer[S]=0;
     55     while(h<t)
     56     {
     57         sta=q[h++];
     58         for(int i=head[sta];~i;i=next[i])
     59             if(len[i]&&layer[to[i]]<0)
     60             {
     61                 layer[to[i]]=layer[sta]+1;
     62                 q[t++]=to[i];
     63             }
     64     }
     65     return layer[T]!=-1;
     66 }
     67 
     68 inline int find(int u,int cur_flow)
     69 {
     70     if(u==T) return cur_flow;
     71     int res=0,tmp;
     72     for(int i=head[u];~i&&res<cur_flow;i=next[i])
     73         if(len[i]&&layer[to[i]]==layer[u]+1)
     74         {
     75             tmp=find(to[i],min(cur_flow-res,len[i]));
     76             len[i]-=tmp; len[i^1]+=tmp; res+=tmp;
     77         }
     78     if(!res) layer[u]=-1;
     79     return res;
     80 }
     81 
     82 inline void go()
     83 {
     84     if(n<=1) {printf("%d\n",n); return;}
     85     int ans=n;
     86     for(S=1;S<=n;S++)
     87         for(T=S+1;T<=n;T++)
     88             if(map[S][T]==0)
     89             {
     90                 build();
     91                 T+=n;
     92                 int tmp=0;
     93                 while(bfs()) tmp+=find(S,INF);
     94                 ans=min(tmp,ans);
     95             }
     96     printf("%d\n",ans);
     97 }
     98 
     99 int main()
    100 {
    101     while(scanf("%d%d",&n,&m)!=EOF) read(),go();
    102     return 0;
    103 } 
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    [LeetCode] 303. 区域和检索
    [LeetCode] 120. 三角形最小路径和 ☆☆☆(动态规划 范例)
    [LeetCode] 18. 四数之和 ☆☆☆(双指针)
    [LeetCode] 16. 最接近的三数之和 ☆☆☆(双指针)
    [LeetCode] 109. 有序链表转换二叉搜索树 ☆☆☆(递归)
    优惠券模块设计要点
    nginx upstream 实现负载均衡
    nginx fastcgi配置
    nginx rewrite规则
    nginx Location 配置
  • 原文地址:https://www.cnblogs.com/proverbs/p/2848490.html
Copyright © 2011-2022 走看看