标签:
题目链接:http://poj.org/problem?id=1523
题目大意:有多组数据,要你求出每组数据的割点,并输出这个割点所在的块数
算法实现:
割点是什么:一个无向连通图去掉一个点及与这个点相连的后,这个无向图分为多个互不连通的子块,这个点则称为割点
时间戳是什么:在搜索时访问的最早时间
算法:tarjan算法
维护dfn[u]表示u的时间戳
low[u]表示u点所能回到的最早的祖先的时间戳
cut[u]表示u点所属于的块的数量
判断割点的条件 dfn[u]>=low[v] //v点及其所在的块没有一条边指向u点以上的点
cut数组开始赋1 //每个点至少属于一个块
每次判断割点条件成立cut[u]++;
最后若cut[u]>=2则u为割点
注意:最开始搜索的点由于时间戳最小,所以肯定满足割点的条件,所以初始值要赋为0
图的存储:链式前向星
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <cstdlib> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <iostream> 9 #include "algorithm" 10 using namespace std; 11 typedef long long LL; 12 const int MAX1=1005; 13 const int MAX2=2505; 14 int n,m; 15 int tot,c,tx; 16 int head[MAX1],adj[MAX2],next[MAX2]; 17 int dfn[MAX1],low[MAX1],sta[MAX1]; 18 bool t[MAX1]; 19 int cut[MAX1]; 20 void addedge(int u,int v){ 21 tot++; 22 adj[tot]=v; 23 next[tot]=head[u]; 24 head[u]=tot; 25 } 26 void dfs(int x,int fa){ 27 t[x]=true; 28 sta[++sta[0]]=x; 29 dfn[x]=low[x]=++c; 30 int i,j; 31 bool flag; 32 flag=true; 33 for (i=head[x];i;i=next[i]) 34 {if (adj[i]==fa && flag) 35 {flag=true; 36 continue; 37 } 38 if (t[adj[i]]) 39 low[x]=min(low[x],dfn[adj[i]]); 40 else 41 {dfs(adj[i],x); 42 low[x]=min(low[x],low[adj[i]]); 43 if (low[adj[i]]>=dfn[x]) 44 {while (sta[sta[0]]!=x) 45 {sta[0]--; 46 } 47 cut[sta[sta[0]]]++; 48 } 49 } 50 } 51 } 52 int main(){ 53 freopen ("SPF.in","r",stdin); 54 freopen ("SPF.out","w",stdout); 55 int i,j;int cas;cas=0; 56 int u,v; 57 while (1){ 58 scanf("%d",&u); 59 if (u==0) 60 break; 61 printf("Network #%d\n",++cas); 62 memset(next,0,sizeof(next)); 63 memset(head,0,sizeof(head)); 64 memset(adj,0,sizeof(adj)); 65 memset(dfn,0,sizeof(dfn)); 66 memset(low,0,sizeof(low)); 67 memset(cut,0,sizeof(cut)); 68 memset(t,false,sizeof(t)); 69 tx=sta[0]=c=n=m=0; 70 while (1) 71 {scanf("%d",&v); 72 m++; 73 n=max(n,max(u,v)); 74 addedge(u,v); 75 addedge(v,u); 76 scanf("%d",&u); 77 if (u==0) 78 break; 79 } 80 for (i=1;i<=n;i++) 81 if (!t[i]) 82 {cut[i]=-1; 83 dfs(i,i); 84 } 85 bool flag=true; 86 for (i=1;i<=n;i++) 87 if (cut[i]>0) 88 {flag=false; 89 printf(" SPF node %d leaves %d subnets\n",i,cut[i]+1); 90 } 91 if (flag) puts(" No SPF nodes"); 92 putchar(‘\n‘); 93 } 94 return 0; 95 } 96
标签:
原文地址:http://www.cnblogs.com/Michaelzzn/p/5559442.html