zoukankan      html  css  js  c++  java
  • poj 1966(求点连通度,边连通度的一类方法)

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

    思路:从网上找了一下大牛对于这类问题的总结:图的连通度问题是指:在图中删去部分元素(点或边),使得图中指定的两个点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】)处理。

    于是对于本题我们可以枚举源点和汇点求解。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 using namespace std;
      7 #define MAXN 111
      8 #define inf 1<<30
      9 
     10 struct Edge{
     11     int v,cap,next;
     12 }edge[MAXN*MAXN];
     13 
     14 int n,m,NE,NV;
     15 int head[MAXN];
     16 
     17 void Insert(int u,int v,int cap)
     18 {
     19     edge[NE].v=v;
     20     edge[NE].cap=cap;
     21     edge[NE].next=head[u];
     22     head[u]=NE++;
     23 
     24     edge[NE].v=u;
     25     edge[NE].cap=0;
     26     edge[NE].next=head[v];
     27     head[v]=NE++;
     28 }
     29 
     30 int level[MAXN],gap[MAXN];
     31 void bfs(int vt)
     32 {
     33     memset(level,-1,sizeof(level));
     34     memset(gap,0,sizeof(gap));
     35     level[vt]=0;
     36     gap[level[vt]]++;
     37     queue<int>que;
     38     que.push(vt);
     39     while(!que.empty()){
     40         int u=que.front();
     41         que.pop();
     42         for(int i=head[u];i!=-1;i=edge[i].next){
     43             int v=edge[i].v;
     44             if(level[v]!=-1)continue;
     45             level[v]=level[u]+1;
     46             gap[level[v]]++;
     47             que.push(v);
     48         }
     49     }
     50 }
     51 
     52 int pre[MAXN],cur[MAXN];
     53 int SAP(int vs,int vt)
     54 {
     55     bfs(vt);
     56     memset(pre,-1,sizeof(pre));
     57     memcpy(cur,head,sizeof(head));
     58     int maxflow=0,aug=inf;
     59     int u=pre[vs]=vs;
     60     gap[0]=NV;
     61     while(level[vs]<NV){
     62         bool flag=false;
     63         for(int &i=cur[u];i!=-1;i=edge[i].next){
     64             int v=edge[i].v;
     65             if(edge[i].cap>0&&level[u]==level[v]+1){
     66                 flag=true;
     67                 pre[v]=u;
     68                 u=v;
     69                 aug=min(aug,edge[i].cap);
     70                 if(v==vt){
     71                     maxflow+=aug;
     72                     for(u=pre[v];v!=vs;v=u,u=pre[u]){
     73                         edge[cur[u]].cap-=aug;
     74                         edge[cur[u]^1].cap+=aug;
     75                     }
     76                     aug=inf;
     77                 }
     78                 break;
     79             }
     80         }
     81         if(flag)continue;
     82         int minlevel=NV;
     83         for(int i=head[u];i!=-1;i=edge[i].next){
     84             int v=edge[i].v;
     85             if(edge[i].cap>0&&level[v]<minlevel){
     86                 minlevel=level[v];
     87                 cur[u]=i;
     88             }
     89         }
     90         if(--gap[level[u]]==0)break;
     91         level[u]=minlevel+1;
     92         gap[level[u]]++;
     93         u=pre[u];
     94     }
     95     return maxflow;
     96 }
     97 
     98 bool map[MAXN][MAXN];
     99 void Build()
    100 {
    101     NE=0;
    102     memset(head,-1,sizeof(head));
    103     for(int i=0;i<n;i++){
    104         for(int j=0;j<n;j++){
    105             if(i==j)Insert(i,i+n,1);
    106             else if(map[i][j])Insert(i+n,j,inf);
    107         }
    108     }
    109 }
    110 
    111 int main()
    112 {
    113  //   freopen("1.txt","r",stdin);
    114     int u,v,ans;
    115     while(~scanf("%d%d",&n,&m)){
    116         NV=2*n;
    117         memset(map,false,sizeof(map));
    118         while(m--){
    119             scanf(" (%d,%d)",&u,&v);
    120             map[u][v]=map[v][u]=true;
    121 
    122         }
    123         ans=inf;
    124         for(int vs=0;vs<n;vs++){
    125             for(int vt=vs+1;vt<n;vt++){
    126                 Build();
    127                 ans=min(ans,SAP(vs+n,vt));
    128             }
    129         }
    130         if(ans>=n)ans=n;
    131         printf("%d
    ",ans);
    132     }
    133     return 0;
    134 }
    View Code
  • 相关阅读:
    Camera HAL3学习
    Android GPU呈现模式分析
    Android O版本自定义日志输出目录
    Android Configstore HAL
    Ubuntu下设置adb path的方法
    Ubuntu使用技巧
    PHP学习笔记
    mysql安装
    在ubuntu中安装Python
    OS X在使用<semaphore.h>时报错
  • 原文地址:https://www.cnblogs.com/wally/p/3282974.html
Copyright © 2011-2022 走看看