1. 程式人生 > >POJ 1523 SPF 求割點的好(板子)題!

POJ 1523 SPF 求割點的好(板子)題!

algo namespace net () 參考 tin space nod poj

題意:

給個無向圖,問有多少個割點,對於每個割點求刪除這個點之後會產生多少新的點雙聯通分量


題還是很果的

怎麽求割點請參考tarjan無向圖

關於能產生幾個新的雙聯通分量,對於每個節點u來說,我們判斷他是否是割點,即判斷是否滿足他的兒子v的low[v]>dfn[u]

而這個時候割掉這個點就會讓雙聯通分量增加,所以搞一個數組記錄一下這個操作的次數就行

請註意在是否是根節點的問題上特判

!!註意輸出格式!!

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define
N 5010 5 #define M 10100 6 #define Max(a,b,c) max(max(a,b),c) 7 using namespace std; 8 int head[N],n,m,ecnt=2,u,v,dfn[N],low[N],indx,du[N],ans,isap[N],ap,task,sum[N]; 9 struct edge 10 { 11 int u,v,nxt; 12 }e[M*2]; 13 void add(int u,int v) 14 { 15 e[ecnt].v=v; 16 e[ecnt].nxt=head[u]; 17 e[ecnt].u=u;
18 head[u]=ecnt++; 19 e[ecnt].v=u; 20 e[ecnt].nxt=head[v]; 21 e[ecnt].u=v; 22 head[v]=ecnt++; 23 } 24 void dfs(int u,int fa) 25 { 26 dfn[u]=low[u]=++indx; 27 int n_ch=0; 28 for (int i=head[u];i;i=e[i].nxt) 29 { 30 int v=e[i].v; 31 if (!dfn[v]) 32 { 33 dfs(v,i);
34 low[u]=min(low[u],low[v]); 35 if (low[v]>=dfn[u]) 36 isap[u]=1,ap++,sum[u]++; 37 n_ch++; 38 } 39 else 40 if (v!=fa) 41 low[u]=min(dfn[v],low[u]); 42 } 43 if (fa==-1 && n_ch==1) 44 isap[u]=0,ap--; 45 if (isap[u] && fa!=-1) sum[u]++; 46 } 47 void init() 48 { 49 n=0; 50 memset(sum,0,sizeof(sum)); 51 memset(head,0,sizeof(head)); 52 memset(dfn,0,sizeof(dfn)); 53 memset(isap,0,sizeof(isap)); 54 ecnt=2; 55 ans=0; 56 indx=0; 57 ap=0; 58 } 59 void solve() 60 { 61 if (n==0) return; 62 task++; 63 for (int i=1;i<=n;i++) 64 if (!dfn[i]) dfs(i,-1); 65 printf("Network #%d\n",task); 66 if (ap==0) 67 printf(" No SPF nodes\n"); 68 for (int i=1;i<=n;i++) 69 if (isap[i]) 70 printf(" SPF node %d leaves %d subnets\n",i,sum[i]); 71 putchar(\n); 72 init(); 73 } 74 int main() 75 { 76 // freopen("1.in","r",stdin); 77 while (1) 78 { 79 while (scanf("%d",&u)!=EOF) 80 { 81 if (u==0) 82 { 83 solve(); 84 continue; 85 } 86 if (scanf("%d",&v)==EOF) break; 87 n=Max(n,u,v); 88 add(u,v); 89 // printf("%d %d\n",u,v); 90 } 91 if (n==0) break; 92 } 93 return 0; 94 }

POJ 1523 SPF 求割點的好(板子)題!