1. 程式人生 > >LOJ-10103(求刪去割點後最多的連通分量)

LOJ-10103(求刪去割點後最多的連通分量)

ide gif -- ring con img str 多次 stream

題目鏈接:傳送門

思路:

(1)這道題的圖可能不連通,所以需要多次Tarjan;

(2)設置cut[i]=x數組表示第i個節點被刪除後右多少個子圖(這個只是在一個圖中),如果是根節點就要-1,因為根節點都滿足

num[v]==low[u].

(3)mx的初始值設為最小值(-9999999),因為有可能cur[i]=-1,存在根節點所在的圖是雙聯通圖。

參考文章:傳送門

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using
namespace std; const int maxn = 100100; int num[maxn],low[maxn],cut[maxn],tim; vector <int> vc[maxn]; void Init() { memset(num,0,sizeof(num)); memset(low,0,sizeof(low)); memset(cut,0,sizeof(cut)); for(int i=0;i<maxn;i++) vc[i].clear(); tim=0; } void Tarjan(int u,int pre) { int
i,v; num[u]=low[u]=++tim; for(int i=0;i<vc[u].size();i++){ v=vc[u][i]; if(!num[v]){ Tarjan(v,u); low[u]=min(low[u],low[v]); if(num[u]<=low[v]) cut[u]++; } else if(pre!=v) low[u]=min(low[u],num[v]); } } int main(void
) { int n,m,i,j,x,y; while(~scanf("%d%d",&n,&m)&&(n+m)){ Init(); for(i=0;i<m;i++){ scanf("%d%d",&x,&y); vc[x].push_back(y); vc[y].push_back(x); } int cnt=0,mx=-99999999; for(i=0;i<n;i++) if(!num[i]){ Tarjan(i,-1); cnt++;cut[i]--; } for(i=0;i<n;i++) mx=max(mx,cut[i]); printf("%d\n",mx+cnt); } return 0; }
View Code

LOJ-10103(求刪去割點後最多的連通分量)