题目链接:传送门
题目大意:一副无向图,问有多少个节点满足删除该节点后图不连通,对于每个满足条件的节点,输出节点编号及删除节点将图分为几个连通块。若没有节点满足则输出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(" "); 92 printf("Network #%d ",++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 ",i,area[i]+1); 99 } 100 if(!flag) printf(" No SPF nodes "); 101 } 102 return 0; 103 }