統計圖中連通塊的數量以及連通塊中點的個數(遞迴和非遞迴)
阿新 • • 發佈:2020-12-08
/* 上一道是根據割點判斷可以割出多少個連通塊來 對於每個圖,割某個點,產生連通塊的數量最大是多少. 一個割點編號對應一個剩餘連通塊的最大值.統計有幾個最大值 how to 求連通塊,怎麼求每個連通塊中點的個數 對v-dcc縮點之後,每個v-dcc的度數就是這個v-dcc連著幾個割點 分別看每個連通塊,設連通塊中點的個數是cnt 如果連通塊中沒有割點,那麼ans= c(cnt,2); 如果連通塊中有割點 1.如果有n個v-dcc的度數為1,那麼建n的出口 2.如果v-dcc的度數為2,說明這個v-dcc連線著兩個割點,無論是v-dcc中的點還是割點坍塌,一定可以通過 別的點逃脫 */ #include<iostream> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int N=2*510,M=510; int h[N],e[M],ne[M],idx; int low[N],dfn[N],tim; int d[N];//每個v-dcc的度數 long long ans=0; void add(int a,int b) { e[idx]=b,ne[idx]=h[a],h[a]=idx++; } int cnt; vector<int>v[N]; int num[N];//儲存連通塊中點的個數 void dfs(int u) { dfn[u]=1; v[cnt].push_back(u);//節點u是第cnt個連通塊中的點 int sum=0;//必須從0開始,最後再加1 // num[cnt]++; for(int i=h[u];~i;i=ne[i]) { int j=e[i]; if(!dfn[j]) sum++,dfs(j); } num[cnt]+=sum;//+= } int main() { int m,flag=1; while(cin>>m,m) { int n=-1; idx=0; memset(h,-1,sizeof h); while(m--) { int a,b;cin>>a>>b; n=max(a,n); n=max(b,n); add(a,b); add(b,a); } // cout<<n<<endl; for(int i=1;i<=n;i++) if(!dfn[i]) cnt++,dfs(i); cout<<cnt<<endl;//連通塊的數量 for(int i=1;i<=cnt;i++) cout<<num[i]<<endl; cout<<"---"<<endl; for(int i=1;i<=cnt;i++) cout<<v[i].size()<<endl; } }