連通性判斷
【試題描述】
無向圖,包含n個節點編號1至n,初始沒有邊。
現在逐次向圖中添加m條邊,你需要在添加邊之前判斷該兩點是否連通。
【輸入要求】
第一行兩個正整數n、m。
接下來m行,每行兩個正整數x、y。
【輸出要求】
m行,每行包含一個整數0或1,0表示添加這條邊之前兩個點不連通,1表示連通。
【輸入實例】
4 5 1 2 1 3 2 3 4 4 3 4
【輸出實例】
0 0 1 1 0
【其他說明】
n,m<=300000。
【試題分析】
用並查集做,這是一道全世界最水的圖論題,直接不用說,上代碼……
【代碼】
#include<iostream> using namespace std; int x,y,f[301001],n,m; int find(int x) { if (f[x]==x) return f[x]; return f[x]=find(f[x]); } void merge(int v,int u) { int t1,t2; t1=find(v); t2=find(u); if(t1!=t2) f[t2]=t1; return ; } inline int read() { int x,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); return x*f; } inline void write(int x) { if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) { bool w=false; x=read(),y=read(); if(find(x)!=find(y)) w=true;//如果x和y的根一樣那么就可以知道這兩條邊加進去以后圖是連通的 if(w==false)write(1),printf("\n"); else write(0),printf("\n"); merge(x,y);//把x和y連起來 } }