19號(hào)學(xué)校要考試了,檢測(cè)大家寒假預(yù)習(xí)情況…… 題目大意:一個(gè)無向圖上有N個(gè)點(diǎn),有m條邊,要按順序刪點(diǎn),按次序輸出每次刪點(diǎn)后圖中的連通塊數(shù)量。 因?yàn)閯h點(diǎn)的操作實(shí)現(xiàn)過于復(fù)雜,所以我們可以考慮倒著來將一個(gè)個(gè)點(diǎn)加入圖中,通過并查集來求出連通塊數(shù)量。
#include <cstdio>#include <vector>using namespace std;#define rover 10000inline char tc(void){ static char fl[rover+1],*A=fl,*B=fl; return A==B?B=(A=fl)+fread(fl,1,rover,stdin),A==B?EOF:*A++:*A++;}#define C (c=tc())inline void read(int &a){ a=0;static char c; int f=1; while(C<'0'||c>'9') c=='-'?f=-1:0; while(c>='0'&&c<='9') a=a*10+c-'0',C; a*=f; return ;}int n,m,x,y,k,od[400002],f[400002],tot,sum,ans[400002];vector<int> s[400002];bool b[400002];int gf(int x){ return x==f[x]?x:f[x]=gf(f[x]);}int main(void){ register int i,j; read(n),read(m); for (i=0;i<n;++i) f[i]=i; for (i=1;i<=m;++i) read(x),read(y),s[x].push_back(y),s[y].push_back(x); read(k); for (i=1;i<=k;++i) read(od[i]),b[od[i]]=1; for (i=0;i<n;++i) if(b[i]==0) { ++sum; for (j=0;j<s[i].size();++j) if(b[s[i][j]]==0&&gf(i)!=gf(s[i][j])) --sum,f[f[i]]=f[s[i][j]]; } ans[tot=k+1]=sum; while(k) { ++sum; b[od[k]]=0; for (j=0;j<s[od[k]].size();++j) if(b[s[od[k]][j]]==0&&gf(od[k])!=gf(s[od[k]][j])) --sum,f[f[od[k]]]=f[s[od[k]][j]]; ans[k]=sum; --k; } for (i=1;i<=tot;++i)新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注