SPF POJ - 1523 割点+并查集

题意:

问你这个图中哪个点是割点,如果把这个点去掉会有几个子网

代码:

  1 //给你几个点,用着几个点形成了一个图。输入边形成的图,问你这个图中有多少个割点。每一个割点去掉后会形成几个强连通分量 
  2 //方法:
  3 //你可以想用tarjan算法求出来谁是割点。然后每一个割点单独用并查集判断。用所有边(不和这个割点相连的边)通过并查集判断一下 
  4 //然合并后有几个区域就可以了
  5 #include<stdio.h>
  6 #include<string.h>
  7 #include<algorithm>
  8 using namespace std;
  9 const int spot=1010;
 10 const int edge=500010;
 11 struct node
 12 {
 13     int u,v;
 14 }m[edge];
 15 struct stu
 16 {
 17     int to,next;
 18 } a[edge];
 19 int head[spot],fa,low[spot],num[spot],root,indexx,sizes,flag1,n,fx[spot],qua,len,v[spot];  //fx指祖节点
 20 bool flag[spot],flag2[spot],b[spot],have[spot];
 21 void init()
 22 {
 23     indexx=0,sizes=0,flag1=1,n=0;
 24     len=qua=0;
 25     memset(head,-1,sizeof(head));
 26     memset(low,0,sizeof(low));
 27     memset(num,0,sizeof(num));
 28     memset(flag,0,sizeof(flag));
 29     memset(have,0,sizeof(have));
 30 }
 31 void add_edge(int from,int to)  //并查集
 32 {
 33     a[sizes].to=to;
 34     a[sizes].next=head[from];
 35     head[from]=sizes++;
 36     a[sizes].to=from;
 37     a[sizes].next=head[to];
 38     head[to]=sizes++;
 39     n=max(n,from);
 40     n=max(n,to);
 41     m[len].u=from;
 42     m[len++].v=to;
 43 }
 44 void dfs(int cur)  //求割点
 45 {
 46     int child=0;
 47     num[cur]=++indexx;
 48     low[cur]=indexx;
 49     int k,v;
 50     for(k=head[cur]; k+1; k=a[k].next)
 51     {
 52         v=a[k].to;
 53         if(!num[v])
 54         {
 55             dfs(v);
 56             low[cur]=min(low[cur],low[v]);
 57             if(low[v]>=num[cur])
 58             {
 59                 child++;
 60                 if(cur!=fa || child>1) flag[cur]=1,qua++;
 61             }
 62         }
 63         else 
 64             low[cur]=min(low[cur],num[v]);
 65     }
 66 }
 67 int finds(int x)
 68 {
 69     if(x!=v[x])
 70     {
 71         int y=finds(v[x]);
 72         return v[x]=y;
 73     }
 74     return x;
 75 }
 76 int panduan(int x)
 77 {
 78     for(int i=1;i<=n;++i)
 79     {
 80         if(have[i]) v[i]=i;
 81     }
 82     for(int i=0;i<len;++i)
 83     {
 84         if(m[i].u!=x && m[i].v!=x)
 85         {
 86             int fx=finds(m[i].u);
 87             int fy=finds(m[i].v);
 88             if(fx!=fy) v[fx]=fy;
 89         }
 90     }
 91     int ans=0;
 92     for(int i=1;i<=n;++i)
 93     {
 94         if(i!=x && v[i]==i) ++ans; 
 95     }
 96     return ans;
 97 }
 98 int main()
 99 {
100     int x,y,i,ss=0,ans,j;
101     while(scanf("%d",&x)&&x)
102     {
103         init();
104         scanf("%d",&y);
105         root=x;    
106         have[x]=1;
107         have[y]=1;
108         add_edge(x,y);
109         for(;;)
110         {
111             scanf("%d",&x);
112             if(!x) break;
113             scanf("%d",&y);
114             add_edge(x,y);
115             have[x]=1,have[y]=1;
116         }
117         fa=root;
118         dfs(root);  
119         printf("Network #%d\n",++ss);
120         for(i=1; i<=n; i++)
121         {
122             if(flag[i])
123             {
124                 flag1=0;
125                 int q=panduan(i);
126                 printf("  SPF node %d leaves %d subnets\n",i,q);
127             }
128         }
129         if(flag1)
130             printf("  No SPF nodes\n");
131         printf("\n");
132     }
133     return 0;
134 }

猜你喜欢

转载自www.cnblogs.com/kongbursi-2292702937/p/11666620.html