POJ 1861

来源:互联网 发布:macbook装windows系统 编辑:程序博客网 时间:2024/04/25 16:09

题目大意:

某公司需要用线缆将网络中的结点连接起来,每两个结点之间有一个权值,选择若干条线缆,要求是任意两个点之间可达,并且要使最长的线缆最小。


思路:

本质上将就是一个最小生成树的例子,因为这里要输出最长的线缆长度,所以用Kruskal算法较为便捷。 Kruskal算法就是 不断地选择不构成环的最小的边。不构成环,这里用的是 并查集,看看两者是不是可达。 这里着重讲一下并查集。首先,初始化将每个点作为一个单独的集合,然后如果a与b可达,那么将a和b放在一个集合里。当某个时刻发现两个点在一个集合里,那么它们势必可构成环。

本题中,注意边最大有15000,开始我用一个数组来保存已选边的两个点,那么该数组最大长度就应该是15000*150000,结果runtime了一次。后来学聪明了,同样用一个ans[MAX] 结构体来保存已选边的两点信息,只是不给w赋值。


#include <iostream>#include <algorithm>using namespace std;#define MAX 15010int p[1010];struct Edge{    int u;    int v;    int w;}map[MAX],ans[MAX];bool cmp(Edge a,Edge b){    return a.w<b.w;}int Find(int a){    return a==p[a]?a:a=Find(p[a]);}int main(){    int N,M,i;    int a,b,c;    cin>>N>>M;    for(i=0;i<=N;i++){        p[i] = i;    }    for(i=0;i<M;i++){        cin>>a>>b>>c;        map[i].u = a;        map[i].v = b;        map[i].w = c;    }    sort(map,map+M,cmp);    int count = 0;    int maxEdge = 0;    for(i=0;i<M;i++){        int x = Find(map[i].u);        int y = Find(map[i].v);        if(x != y){            p[x] = y;            ans[count].u = map[i].u;            ans[count].v = map[i].v;            count ++;            if(map[i].w>maxEdge)                maxEdge = map[i].w;        }    }    cout<<maxEdge<<endl;    cout<<count<<endl;    for(i=0;i<count;i++)        cout<<ans[i].u<<" "<<ans[i].v<<endl;    return 0;}


0 0
原创粉丝点击