zoukankan      html  css  js  c++  java
  • hdoj 1875 畅通project再续【最小生成树 kruskal && prim】

    畅通project再续


    Problem Description
    相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其它的小岛时都要通过划小船来实现。

    如今政府决定大力发展百岛湖。发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!

    经过考察小组RPRush对百岛湖的情况充分了解后。决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。

    当然,为了节省资金。仅仅要求实现随意2个小岛之间有路通就可以。当中桥的价格为 100元/米。

     

    Input
    输入包含多组数据。输入首先包含一个整数T(T <= 200),代表有T组数据。
    每组数据首先是一个整数C(C <= 100),代表小岛的个数。接下来是C组坐标。代表每一个小岛的坐标。这些坐标都是 0 <= x, y <= 1000的整数。
     

    Output
    每组输入数据输出一行,代表建桥的最小花费。结果保留一位小数。假设无法实现project以达到所有畅通,输出”oh!”.
     

    Sample Input
    2 2 10 10 20 20 3 1 1 2 2 1000 1000
     

    Sample Output
    1414.2 oh!
     

    Author
    8600
     

    Source
     



    AC代码:

    kruskal:

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    int per[111];
    double x[111],y[111];
    struct node{
    	int start,end;
    	double distance;
    };
    node p[10000];
    int cmp(node a,node b)	//距离从小到大 
    {
    	return a.distance < b.distance;
    }
    void init()
    {
    	for(int i = 1;i < 111;i++ )
    		per[i] = i;
    }
    int find(int x)
    {
    	if(x == per[x])
    		return x;
    	return per[x] = find(per[x]);	
    }
    bool join(int x,int y)
    {
    	int fx = find(x);
    	int fy = find(y);
    	if(fx != fy)  //推断是否成环 
    	{
    		per[fx] = fy;
    		return true;  //没成环 
    	}
    	return false;	
    }
    int main()
    {
    	int i,j,k;
    	int t,n,c;
    	double d,cost;  //一定要注意题目所要求的数据类型 
    	scanf("%d",&t);
    	while(t--)
    	{
    		init();
    		scanf("%d",&c);
    		for(i = 1;i <= c; i++)
    		{
    			scanf("%lf%lf",&x[i], &y[i]);
    		}
    		k = 0;
    		for(i = 1;i <= c;i++)
    		{
    			for(j = i+1;j <= c;j++)
    			{
    				d = sqrt( (x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]) );//距离公式 
    				if(d >=10.0 && d <= 1000.0)	//一定要筛选完再存进结构体 要不然会WA.
    				{							
    					p[k].start = i;   //起点 
    					p[k].end = j;	  //终点 
    					p[k].distance = d;//起点到到终点的距离 
    					k++;
    				}
    			}
    		}
    		sort(p,p+k,cmp);   //按距离从小到大排序 
    		int num = 0;
    		cost = 0.0;
    		for( i = 0;i < k; i++)
    		{
    			if(join(p[i].start, p[i].end))
    			cost += p[i].distance;
    		}
    		for( i = 1;i <= c;i++ )
    		{
    			if(per[i]==i)
    			num++;
    			if(num > 1)		// 及时跳出循环节省时间 
    			break;
    		}
    		if(num>1)  //无法连接全部小岛 
    			printf("oh!
    ");
    		else
    			printf("%.1lf
    ",100*cost);
    	}
    	return 0;
    }



    ===============================切割线======================================

    prim:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define mem(a, b) memset(a, (b), sizeof(a))
    #define Wi(a) while(a--)
    #define Si(a) scanf("%d", &a)
    #define Pi(a) printf("%d
    ", (a))
    #define Pf(a) printf("%.1lf
    ", (a))
    #define INF 0x3f3f3f
    double map[150][150];
    int x[150],y[150];
    int n;
    double d[150], vis[150];
    void prim()
    {
    	mem(vis, 0);
    	int i, j, k;
    	double ans = 0, minn;
    	for(i = 1; i <= n; i++)
    		d[i] = map[1][i];
    	vis[1] = 1;
    	for(i = 1; i < n; i++)
    	{
    		k = 1;
    		minn = INF;
    		for(j = 1; j <= n; j++)
    		{
    			if(!vis[j] && d[j] < minn)
    			{
    				minn = d[j];
    				k = j;
    			}
    		}
    		if(minn == INF){
    			puts("oh!");return;
    		}
    		vis[k] = 1;
    		ans += minn;
    		for(j = 1; j <= n; j++)
    		{
    			if(!vis[j] && d[j] > map[j][k])
    				d[j] = map[j][k];
    		}
    	}
    	Pf(ans*100);
    } 
    int main(){
    	int t; Si(t);
    	Wi(t){
    		Si(n);
    		int i , j, k;
    		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++)
    			{
    				double d = sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]));
    				if(d >= 10.0 && d <= 1000.0)
    					map[i][j] = map[j][i] =  d;
    				else
    					map[i][j] = map[j][i] = INF;
    			}
    			map[i][i] = 0;
    		}
    		prim();
    	}
    	return 0;
    }




  • 相关阅读:
    LoadRunner压力测试心得总结
    Http和Socket连接区别
    转:Socket服务器整体架构概述
    Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解 (转载)
    LoadRunner中winsocket协议学习
    Digest Authentication 摘要认证
    Http Digest认证协议
    Http authentication(BASIC, DIGEST)
    redis php 执行命令时,单引号和双引号的区别。
    php 生成下载连接
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6812581.html
Copyright © 2011-2022 走看看