1. 程式人生 > 實用技巧 >NC7501D Router Mesh (去掉割點算連通快的變化)

NC7501D Router Mesh (去掉割點算連通快的變化)

題意:

給出一個圖,按序輸出去掉第i個點,剩下的連通快數量。

題解:

割點魔改。

#include<cstdio>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
const int maxn=3e5+100;
vector<int> g[maxn];
int N,M,x,y; 
int low[maxn];
int dfn[maxn];
int cnt;
int scc;
int pos[maxn];
int isGedian[maxn]; int isRoot[maxn]; int cut[maxn]; stack<int> st; void init () { fill (low,low+maxn,0); fill (dfn,dfn+maxn,0); fill (pos,pos+maxn,0); fill (isGedian,isGedian+maxn,0); fill (cut,cut+maxn,0); for (int i=0;i<maxn;i++) g[i].clear(); while (!st.empty()) st.pop(); cnt
=0; scc=0; } void tarjan (int x,int pre) { low[x]=dfn[x]=++cnt; int son=0; st.push(x); for (int i=0;i<g[x].size();i++) { if (g[x][i]==pre) continue; if (!dfn[g[x][i]]) { son++; tarjan(g[x][i],x); low[x]=min(low[x],low[g[x][i]]);
if ((low[g[x][i]]>=dfn[x]&&x!=pre)||(son>1&&x==pre)) cut[x]++; } else if (dfn[g[x][i]]<dfn[x]&&g[x][i]!=pre) low[x]=min(low[x],dfn[g[x][i]]); } } int father[maxn]; int size[maxn]; int findfather (int x) { int a=x; while (x!=father[x]) { x=father[x]; } while (a!=father[a]) { int z=a; a=father[a]; father[z]=x; } return x; } void Union (int x,int y) { x=findfather(x); y=findfather(y); father[x]=y; size[y]+=size[x]; } int main () { while (~scanf("%d%d",&N,&M)) { init (); for (int i=1;i<=N;i++) size[i]=1,father[i]=i; for (int i=1;i<=M;i++) { int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); Union(x,y); } int sum=0; for (int i=1;i<=N;i++) if (!low[i]) tarjan(i,i),sum++; for (int i=1;i<=N;i++) { //printf("%d %d\n",findfather(i),size[i]); if (findfather(i)==i&&size[i]==1) { printf("%d ",sum-1); } else printf("%d ",sum+cut[i]); } printf("\n"); } return 0; }