POJ 1751Highways Kruskal求解

来源:互联网 发布:淘宝网羊毛衫烟火726 编辑:程序博客网 时间:2024/06/08 22:07

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66965#problem/H

题意:修高速公路问题,求最小连通造价,但是会给出一些已经修好了的边,求需要修剪的边。

思路:这题和POJ 2412 Constructing Roads差不多,用Kruskal逐条加边,只是把Kruskal的求sum值改成存储边值就好了。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;struct edge{    int u,v,w;    bool operator <(const edge&a)const{        return w<a.w;    }}E[600000];int N,M,tot,X[800],Y[800];int vis[751][751],pre[800];vector<int> ans;int find(int x){    int t=x;    while(t!=pre[t]) t=pre[t];    while(x!=t) pre[x]=t,x=pre[x];    return t;}void Kruskal(){    ans.clear();    for(int i=0;i<tot;i++){        int fu=find(E[i].u),fv=find(E[i].v);        if(fu==fv) continue;        pre[fv]=fu;ans.push_back(i);//把求和改成路径就好了    }    for(int i=0;i<ans.size();i++){        int k=ans[i];        cout<<E[k].u<<" "<<E[k].v<<endl;    }}int main(){    //freopen("D:\\in.txt","r",stdin);    while(cin>>N){        for(int i=1;i<=N;i++) scanf("%d %d",X+i,Y+i);        memset(vis,0,sizeof(vis));        for(int i=0;i<=N;i++) pre[i]=i;        cin>>M;        int a,b;        for(int i=0;i<M;i++){            scanf("%d %d",&a,&b);            vis[a][b]=vis[b][a]=1;            pre[find(b)]=find(a);        }        tot=0;        for(int i=1;i<=N;i++) for(int j=1;j<i;j++) if(!vis[i][j]){            int t=(X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]);            E[tot++]=(edge){i,j,t};        }        if(tot==0) {cout<<endl;continue;}        sort(E,E+tot);        Kruskal();    }    return 0;}


0 0
原创粉丝点击