標籤:多執行個體 add 個數 uva ring ios printf bridge bool
題目連結:https://vjudge.net/contest/67418#problem/B
題意:給一個無向連通圖,求出割點的數量。首先輸入一個N(多執行個體,0結束),下面有不超過N行的數,每行的第一個數字代表後面的都和它存在邊,0表示行輸入的結束。
題解:簡單的求割點模版,所謂割點就是去掉這一個點還有於這個點連結的邊之後使得原來的圖連通塊增加。
由於這是模版題代碼會加上注釋。
#include <iostream>#include <cstring>using namespace std;const int N = 210;const int M = N * N;struct TnT { int v , next; bool cut;//判斷這條邊是不是橋。和這題求割點沒關係。}edge[M];int head[N] , e;//鏈式前向星。int Low[N] , DFN[N] , Stack[N];//和tarjan表示的相同int Index , top;bool Instack[N];bool cut[N];//表示i點是不是割點int add_block[N];//表示去掉這個割點後連通塊增加了多少,當然和這題並沒什麼關係int bridge;//表示橋的數量void init() { memset(head , -1 , sizeof(head)); e = 0;}void add(int u , int v) { edge[e].v = v; edge[e].next = head[u]; head[u] = e++;}void Tarjan(int u , int pre) { int v; Low[u] = DFN[u] = ++Index; Stack[top++] = u; Instack[u] = true; int son = 0;//用來存子樹的個數 for(int i = head[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v; if(v == pre) continue; if(!DFN[v]) { son++; Tarjan(v , u); Low[u] = min(Low[u] , Low[v]); if(Low[v] > DFN[u]) { bridge++; edge[i].cut = true; edge[i ^ 1].cut = true; }//這是求橋的。 if(u != pre && Low[v] >= DFN[u]) { cut[u] = true; add_block[u]++; }//一種情況當u不是根節點時如果存在v點使得low到達的點深度比u點的深度深那麼這u點刪掉之後v肯定和原來的不連通了 } else if(Instack[v]) Low[u] = min(Low[u] , DFN[v]); } if(u == pre && son > 1) cut[u] = true;//另一種情況如果是根節點那麼只要子樹大於1肯定是割點 if(u == pre) add_block[u] = son - 1; Instack[u] = false; top--;}int main() { int n; while(scanf("%d" , &n) != EOF) { if(n == 0) break; int u , v; char End; init(); while(scanf("%d", &u)) { if(u == 0) break; while(1) { scanf("%d%c", &v, &End); add(u, v); add(v, u); if(End == ‘\n‘) break; } }//題目要求的奇葩的輸入方式。 Index = 0 , top = 0 , bridge = 0; memset(DFN , 0 , sizeof(DFN)); memset(cut , false , sizeof(cut)); memset(Instack , false , sizeof(Instack)); memset(Low , 0 , sizeof(Low)); memset(add_block , 0 , sizeof(add_block)); for(int i = 1 ; i <= n ; i++) if(!DFN[i]) Tarjan(i , i); int ans = 0; for(int i = 1 ; i <= n ; i++) if(cut[i]) ans++; printf("%d\n" , ans); } return 0;}
UVA - 315 Network(tarjan求割點的個數)