[水]Poj2349 Kruskal

来源:互联网 发布:350淘宝装修平台app 编辑:程序博客网 时间:2024/06/09 20:13

原因:为了练习一下Kruskal,随便到poj找了一个求mst的题。- -

题意:给一堆城市的坐标点,任何两个城市之间有两种通讯方式,一种是直接卫星通讯,不管两个城市距离多远,都可以通讯,另一种是微波通讯,通讯距离不超过D,D越大成本越高,给出s个城市之间可以用卫星通讯,其他必须得用微波,求所有城市都可以互相通讯的最小成本。

分析:先用Kruskal求出mst,记录mst中的所有边,那么删除了最大的那s-1条边后最大的边就是答案,如果没有边了返回0,不过貌似这题不会所有城市之间都用卫星通讯。还有一个坑爹的地方就是输出时候的占位符必须是%0.2f,这个不能理解。。看了discuss改了才AC。

其他做法:直接二分答案然后验证。。

代码

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <algorithm>#include <cmath>#include <queue>using namespace std;typedef pair<int,int> P;struct edge{   //无向边   int u,v;   double dis;};const int maxe = 2500005;const int maxv = 505;edge e[maxe];P pot[maxv];int V,E,s,res,fa[maxv],height[maxv];bool cmp(edge a1,edge a2){    return a1.dis<a2.dis;}void ini(){    for(int i=1;i<=V;i++)    {        fa[i]=i;        height[i]=0;    }}int findfa(int a){    if(fa[a]==a) return a;    return fa[a]=findfa(fa[a]);}bool same(int a,int b){    return findfa(a)==findfa(b);}void unite(int a,int b){    int faa=findfa(a),fab=findfa(b);    if(height[faa]<height[fab])        fa[faa]=fab;    else    {        fa[fab]=faa;        if(height[faa]==height[fab]) height[faa]++;    }}double Kruscal(){    priority_queue<double> pq;    sort(e+1,e+E+1,cmp);    ini();    for(int i=1;i<=E;i++)    {        edge nowe=e[i];        if(!same(e[i].v,e[i].u))        {            unite(e[i].v,e[i].u);            pq.push(e[i].dis);        }    }    for(int i=1;i<s;i++)    {        pq.top();pq.pop();    }    if(pq.empty()) return 0;    return pq.top();}double get_dis(P a,P b){    return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));}int main(){    //freopen("in.txt","r",stdin);    int t;    scanf("%d",&t);    while(t--)    {      scanf("%d%d",&s,&V);  //已经有卫星通讯的城市数和点数      for(int i=1;i<=V;i++)        scanf("%d%d",&pot[i].first,&pot[i].second);      int th=0;      for(int i=1;i<=V;i++)        for(int j=1;j<i;j++)        {           th++;           e[th].u=i;e[th].v=j;e[th].dis=get_dis(pot[i],pot[j]);        }      E=th;      printf("%0.2f\n",Kruscal()); //这里必须用%0.2f输出 不知道为什么    }    return 0;}


0 0