1. 程式人生 > >並查集模板poj2524

並查集模板poj2524

並查集可以確定連通分量,各邊與各邊的關係。與克魯斯科爾最小生成樹演算法類似。具體模板如下,,,

//初始化函式
void Init(int n)
{
    int i;
    for(i=1;i<=n;i++)
        father[i]=i;
}
//查詢函式
int Find(int x)
{
    return x == father[x] ? x : father[x] = find(father[x]);
}
//合併函式
void combine(int a,int b)
{
    int temp_a,temp_b;
    temp_a=Find(a);
    temp_b=Find(b);

    if
(temp_a!=temp_b) father[temp_a]=temp_b; } //確定連通分量個數 int find_ans(int n) { int i,sum=0; for(i=1;i<=n;++i) if(father[i]==i) ++sum; return sum; }

以poj2524為例

#include<stdio.h>
const int maxn=50010;
int father[maxn];
int n,m,x,y;
void lnit(int n){
    for(int
i=1;i<=n;i++){ father[i]=i; } } int find(int x){ return x == father[x] ? x : father[x] = find(father[x]); } void combine(int a,int b){ int temp_a,temp_b; temp_a=find(a); temp_b=find(b); if(temp_a!=temp_b){ father[temp_a]=temp_b; } } int main(){ int
num=0; while(~scanf("%d%d",&n,&m)){ if(n==0&&m==0)break; num++; lnit(n); for(int i=1;i<=m;i++){ scanf("%d%d",&x,&y); combine(x,y); } int sum=0; for(int i=1;i<=n;i++){ if(find(i)==i){ sum++; } } printf("Case %d: %d\n",num,sum); } }

還有poj1611可以練習練習