1. 程式人生 > >【解題報告】【圖論專題】

【解題報告】【圖論專題】

圖論 克魯斯卡爾 scan 克魯斯卡爾算法 href display ref 排序 span

圖論500題http://blog.csdn.net/luomingjun12315/article/details/47438607

【最小生成樹+並查集】

1、hdu 1856   基礎並查集★

技術分享圖片
/*
轉化為圖論模型
求一個圖的最大聯通分量
用並查集,每個聯通分量用一個集合維護,最後求集合元素個數的最大值 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 10000010;
int fa[maxn];
int ans[maxn];
void
init(){ for(int i=0;i<maxn;++i){ fa[i] = i; } memset(ans , 0, sizeof(ans)); } int find(int u){ return u==fa[u] ? u : fa[u] = find(fa[u]); } void un(int u, int v){ int fu = find(u); int fv = find(v); fa[fv] = fu; } int main(){ int n; while(scanf("%d", &n)==1
){ if(n==0){ printf("1\n"); continue; } init(); int u, v; int maxnum = -1; for(int i=0;i<n;++i){ scanf("%d%d", &u, &v); if(u>maxnum) maxnum = u; if(v>maxnum) maxnum = v;
if(find(u)!=find(v)) un(u, v); } // ///test // for(int i=1;i<=maxnum;++i){ // cout << fa[i] << " "; // } // cout << endl; for(int i=1;i<=maxnum;++i){ ans[find(i)]++; } int maxans = -1; for(int i=1;i<=maxn;++i){ if(ans[i] > maxans) maxans = ans[i]; } printf("%d\n", maxans); } return 0; }
AC

2、hdu 1102   基礎最小生成樹★ 錯誤原因還未找到

技術分享圖片
/*
克魯斯卡爾算法
將邊從小到大排序 
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 10010;
    
struct node{
    int u;
    int v; 
    int weight;
} ;
node edges[maxn];
bool cmp(const node & e1, const node & e2){
    return e1.weight <= e2.weight;
}

int d[105];        //並查集
int find(int u){
    return u==d[u] ? u : d[u] = find(d[u]);
} 
void init(){
    for(int i=0;i<105;++i){
        d[i] = i;
    }
}
void un(int u, int v){
    int fu = find(u);
    int fv = find(v);
    d[fv] = fu;
}

int main(){
    int n;
    int en = 0;
    int w; 
    init();
    scanf("%d", &n);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            scanf("%d", &w);    
            if(j>i){
                edges[en].weight = w;
                edges[en].u = i;
                edges[en].v = j;
                en++;
            }
        }
    }
    
    int q;
    int u, v;
    scanf("%d", &q);
    for(int i=0;i<q;++i){
        scanf("%d%d", &u, &v);
        if(find(u)!=find(v)) un(u, v);
    }

    int ans = 0;
    sort(edges, edges+en, cmp);
    for(int i=0;i<en;++i){
        if(find(edges[i].u) != find(edges[i].v)){
            ans+=edges[i].weight;
            un(edges[i].u, edges[i].v);
        }
    }
    
    printf("%d\n", ans);
    return 0;
}
WA

【解題報告】【圖論專題】