ZOJ1119(SPF)

题目链接:传送门

题目大意:一副无向图,问有多少个节点满足删除该节点后图不连通,对于每个满足条件的节点,输出节点编号及删除节点将图分为几个连通块。若没有节点满足则输出No SPF nodes

题目思路:tarjan算法求关节点入门题(也可用矩阵存图)

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <cstring>
  7 #include <stack>
  8 #include <cctype>
  9 #include <queue>
 10 #include <string>
 11 #include <vector>
 12 #include <set>
 13 #include <map>
 14 #include <climits>
 15 #define lson root<<1,l,mid
 16 #define rson root<<1|1,mid+1,r
 17 #define fi first
 18 #define se second
 19 #define ping(x,y) ((x-y)*(x-y))
 20 #define mst(x,y) memset(x,y,sizeof(x))
 21 #define mcp(x,y) memcpy(x,y,sizeof(y))
 22 #define Min(x,y) (x<y?x:y)
 23 #define Max(x,y) (x>y?x:y)
 24 using namespace std;
 25 #define gamma 0.5772156649015328606065120
 26 #define MOD 100000007
 27 #define inf 0x3f3f3f3f
 28 #define N 1000005
 29 #define maxn 1000050
 30 typedef long long LL;
 31 typedef pair<int,int> PII;
 32 
 33 int n,m,head[1001],hcnt,son,num;
 34 int dfn[1001],low[1001],area[1001],vis[1001];
 35 int deep;
 36 struct Node{
 37     int to,next;
 38     Node(){}
 39     Node(int a,int b):to(a),next(b){}
 40 }node[2000800];
 41 inline void add(int x,int y){
 42     node[hcnt]=Node(y,head[x]);
 43     head[x]=hcnt++;
 44 }
 45 
 46 void init(){
 47     num=0;  ///最大节点的编号
 48     hcnt=0; 
 49     deep=1; ///深度搜索树的深度优先数(第几个被搜索)
 50     son=0;  ///记录根节点的子女个数
 51     low[1]=dfn[1]=1;  ///low表示节点能通过子女和回边到达的最小深度优先数
 52     mst(head,-1);     ///dfn表示节点的深度优先数                      
 53     mst(vis,0);
 54     mst(area,0);  ///记录删除某个节点后图被分成了几块
 55     vis[1]=1; ///标记节点是否访问过
 56 }
 57 
 58 void dfs(int x){
 59     for(int i=head[x];~i;i=node[i].next){
 60         int e=node[i].to;
 61         if(vis[e]) low[x]=Min(low[x],dfn[e]);
 62         else{
 63             vis[e]=1;
 64             dfn[e]=low[e]=++deep;
 65             dfs(e);
 66             low[x]=Min(low[x],low[e]);
 67             if(low[e]>=dfn[x]){
 68                 if(x==1) ++son;
 69                 else ++area[x];
 70             }
 71         }
 72     }
 73 }
 74 
 75 int main(){
 76     int i,j,group,Case=0,x,y;
 77     while(scanf("%d",&x)!=EOF&&x){
 78         init();
 79         num=Max(num,x);
 80         scanf("%d",&y);
 81         num=Max(num,y);
 82         add(x,y);
 83         add(y,x);
 84         while(scanf("%d",&x)&&x){
 85             num=Max(num,x);
 86             scanf("%d",&y);
 87             num=Max(num,y);
 88             add(x,y);
 89             add(y,x);
 90         }
 91         if(Case)printf("\n");
 92         printf("Network #%d\n",++Case);
 93         dfs(1);
 94         if(son>1)area[1]=son-1;
 95         int flag=0;
 96         for(i=1;i<=num;++i)if(area[i]){
 97             flag=1;
 98             printf("  SPF node %d leaves %d subnets\n",i,area[i]+1);
 99         }
100         if(!flag) printf("  No SPF nodes\n");
101     }
102     return 0;
103 }

 

posted @ 2016-05-21 15:58  Kurokey  阅读(208)  评论(0编辑  收藏  举报