• tarjin求割点


    题目: hdu3671

    http://acm.hdu.edu.cn/showproblem.php?pid=3671

    题意:给一个无向图,要求毁掉两个点,使图变得不连通,图一开始是连通的

    因为要毁掉两个点,就不是简单的求割点,再看看数据范围,点数为1000,边数为10000,Tarjan的时间复杂度为O(E),如果用枚举法,先枚举要毁掉的第一个点,再用Tarjan进行处理来找割点会不会超时呢?答案是不会,时间为O(v*E),刚好是千万级别,不超

    做法:先枚举要删除的第1个点,在原图中删除它,看看删除它后整个图的变化

            1.整个图变得不连通了(即这个点本身是割点),但是还没完要分类讨论一下

            (1).整个图变为两部分,但是两部分刚好都是一个点,那么这两个点再毁掉哪个点都好,图的连通分支数都不

    会增加,这是一个特殊情况

          例如,(1,2)(2,3)这种图,是无解的,任意毁掉两个点都无法增加图的连通分支,所以方案数为0

            (2).整个图分为两部分,但是有一部分的点数为1,另一部分大于1,那么这时候只要在较大的那部分,任意毁掉一个点(无论是不是割点都行),最后整个图都会至少被分为了两个部分

                    (如果毁掉的是割点,将分成更多份),所以这样产生的方案数是V-2

            (3).整个图分为了两个部分,两个部分的点数都大于1,那么任意在哪个部分毁掉那个点都可以(无论是不是割点都行),最后整个图都会至少分为两个部分,所以方案数为V-1

            (4).整个图被分为了三个或更多的部分,那么也是在剩下的点中任意毁掉一个点都可以(无论那个点是不是割点),方案数为V-1

                  (如果这个点刚好处于一个部分且这个部分只有它自己一个点,那么    毁掉后整个图的分支数减1;如果这个点在一个部分且这个部分不止它一个点且这个点不是割点,那么分支数  不会增加,如果是割点分支数为增加)

         2.删除第一个点后,整个图还是连通的(是连通,不是双连通)

            那么就在剩下的图中找割点,找到几个,方案数就是多少

    最后注意一点,这样计算的结果,很容易想到是有重复的,但是不难想到,其实刚好重复了一次,因为对于一个图,方案是固定的,枚举了所有点,找出了所有已方案,相当于每个方案算了两次,最后答案除2即可

     1 #include<iostream>
     2 #include<cstring>
     3 //#include<bits/stdc++.h>
     4 #include<math.h>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<stack>
     8 #include<cstdio>
     9 #include<map>
    10 #include<set>
    11 #define  si(a)       scanf("%d",&a)
    12 #define  sl(a)       scanf("%lld",&a)
    13 #define  sii(a,b)    scanf("%d%d",&a,&b)
    14 #define  sll(a,b)    scanf("%lld%lld",&a,&b)
    15 #define  queues      priority_queue
    16 #define mod 1000000007
    17 #define mem(a)  memset(a,0,sizeof(a));
    18 #define def(a) ((a)&(-a))
    19 #define mp make_pair
    20 #define pb push_back
    21 #define  fi first
    22 #define se second
    23 typedef long long ll;
    24 const int INF=0x3f3f3f3f;
    25 using namespace std;
    26 const int MAX=1003;
    27 vector<int>q[MAX];
    28 int DFN[MAX];
    29 int VIM[MAX];
    30 int top;
    31 int clore;
    32 int num;
    33 set<int>s;
    34 void tarjan(int a,int fa,int d)
    35 {
    36     int child=0;
    37     DFN[a]=VIM[a]=++top;
    38     num++;
    39     for(int i:q[a])
    40     {
    41         if(i==fa||i==d)continue;
    42         if(!DFN[i])
    43         {
    44             child++;
    45             tarjan(i,a,d);
    46             VIM[a]=min(VIM[a],VIM[i]);
    47             if(VIM[i]>=DFN[a]&&a!=fa)
    48                 s.insert(a);
    49         }
    50         else VIM[a]=min(VIM[a],DFN[i]);
    51     }
    52     if(a==fa&&child>=2)s.insert(a);
    53 }
    54 int main()
    55 {
    56     int n,m;
    57     int z=0;
    58     while(cin>>n>>m&&n+m)
    59     {
    60         int sum=0;
    61         top=0;
    62         for(int i=1; i<=n; i++)
    63             q[i].clear();
    64         for(int i=1; i<=m; i++)
    65         {
    66             int a,b;
    67             cin>>a>>b;
    68             q[a].push_back(b);
    69             q[b].push_back(a);
    70         }
    71         for(int i=1; i<=n; i++)
    72         {
    73             int count1=0;
    74             int ok=0;
    75             clore=0;
    76             s.clear();
    77             mem(VIM);
    78             mem(DFN);
    79             for(int j=1; j<=n; j++)
    80                 if(j!=i&&!DFN[j])
    81                 {
    82                     count1++;
    83                     num=0;
    84                     tarjan(j,j,i);
    85                     if(num==1)ok++;
    86                 }
    87             if(count1>=3)sum+=n-1;
    88             else if(count1==2&&ok==1)sum+=n-2;
    89             else if(count1==2&&ok==0)sum+=n-1;
    90             else if(count1==1)sum+=s.size();
    91         }
    92         printf("Case %d: %d
    ",++z,sum/2);
    93     }
    94 
    95 }
    View Code
  • 相关阅读:
    Java hibernate 遇到的问题:could not read a hi value
    Java 小知识
    Java 在使用@Select遇到的问题:拼接字符串将数组拼为了字符串
    飞逝的光阴
    终于回来了
    再说创客
    离开一段时间
    抛弃QP
    关于创客
    对DTU系统结构的重新思考
  • 原文地址:https://www.cnblogs.com/zxz666/p/10722663.html
Copyright © 2020-2023  润新知