HDU 1875 畅通工程再续( 基础最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1875

一直超时了,找了好久才发现我把快排比较中的>写成了-。郁闷。

Kruskal算法(基于并查集)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
int v[105];
struct node
{
int x;
int y;
double dis;
}p[10005];
int cmp(const void *a,const void *b)
{
return (*(struct node*)a).dis>(*(struct node*)b).dis?1:-1;
}


int find(int x)
{
if(x!=v[x])
v[x]=find(v[x]);
return v[x];
}
int make(int a,int b)
{
int x,y;
x=find(a);
y=find(b);
if(x==y)
return 0;
v[x]=y;
return 1;
}


int main()
{
int t,n,x[105],y[105],count,i,j,d,k;
double sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
v[i]=i;
for(i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
k=0;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
{
d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
if(d>=100&&d<=1000000)//判断合适的边,用结构体存城市和边权
{
p[k].x=i;
p[k].y=j;
p[k].dis=sqrt(d);
k++;
}
}
qsort(p,k,sizeof(p[0]),cmp);
sum=count=0;
for(i=0;i<k;i++)
{
if(make(p[i].x,p[i].y)==1)
{
sum+=p[i].dis*100;
count++;
}
}
if(count==n-1)
printf("%.1f\n",sum);
else
printf("oh!\n");
}
return 0;
}

Prime算法(基于最短路)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define Max 99999999
int flag[105];
double map[105][105];
double dis[105];


double prime(int n)
{
    int i,w,tep;
double min,sum=0;
    memset(flag,0,sizeof(flag));
    for(i=1;i<=n;i++)
        dis[i]=map[1][i];//起点到其他个点的最初路径长度
    flag[1]=1;//标记已搜过
    w=n-1;
    while(w--)
    {
        min=Max;
        tep=-1;
        for(i=1;i<=n;i++)
        {
            if(flag[i]==0&&min>dis[i])//遍历搜索到最小的dis值,并记录改点编号
            {
                min=dis[i];
                tep=i;
            }
        }
        if(tep==-1)//若mini为无穷大,则表示改点为孤立点,此图不连通,结束循环
        {
            return -999;
            break;
        }
        flag[tep]=1;//把搜到的最小的dis值的顶点编号标记
        sum+=min;//加上权值
        for(i=1;i<=n;i++)
        {
            if(flag[i]==0&&dis[i]>map[tep][i])//更新每个点的dis值,保证最优
                dis[i]=map[tep][i];
        }
    }
    return sum;
}
int main()
{
int t,n,x[105],y[105],i,j,d;
double sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=Max;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
{
d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
if(d>=100&&d<=1000000)
{
map[i][j]=map[j][i]=sqrt(d);
}
}
sum=prime(n);
if(sum==-999)
printf("oh!\n");
else
printf("%.1f\n",sum*100);

}
return 0;
}





猜你喜欢

转载自blog.csdn.net/qq_16707047/article/details/39829355