2.並查集算法以及路徑壓縮
int pre[1000 ];
int find(intx) //查找根節點
{
int r=x;
while ( pre[r ] != r) //返回根節點 r
r=pre[r];
int i=x , j ;
while( i != r) //路徑壓縮
{
j = pre[ i ]; // 在改變上級之前用臨時變量 j 記錄下他的值
pr
}
return r ;
}
將兩點相連
void join(intx,inty) //判斷x y是否連通,
//如果已經連通,就不用管了 //如果不連通,就把它們所在的連通分支合併起,
{
int fx=find(x),fy=find(y);
if(fx!=fy)
pre[fx ]=fy;//接通需要通過兩個父節點進行連接 pre【fx】=fy; 意思是fx的父節點爲fy
}
代碼:
//本程序的本質就是查詢存在的連接數 通過總數減去存在的 得到的就是需要增加的最小連接數
#include<iostream>
using namespace std;
int n,m,a,b;
int sum,pre[10000];
int find(int x)
{
intr;
r=x;
while(pre[r]!=r)
{
r=pre[r];
}
inti=x,j;
while(i!=r)
{
j=pre[i];//¼Ç¼ֵ
pre[i]=r;
i=j;
}
returnr;
}
void join(int x,inty)
{
intfx=find(x),fy=find(y);
if(fx!=fy)
{
pre[fx]=fy;
sum--;
}
}
int main()
{
while(cin>>n&&n)
{
cin>>m;
sum=n-1;
for(inti=1;i<=n;i++)//³õʼ»¯Á¬½Óµã
pre[i]=i;
for(inti=1;i<=m;i++)
{
cin>>a>>b;
join(a,b);
}
cout<<sum<<endl;
}
return0;
}