zoukankan      html  css  js  c++  java
  • PTA 08-图7 公路村村通 (30分)

    题目地址

    https://pta.patest.cn/pta/test/15/exam/4/question/718

    5-10 公路村村通   (30分)

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

    输入格式:

    输入数据包括城镇数目正整数NN(le 10001000)和候选道路数目MM(le 3N3N);随后的MM行对应MM条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到NN编号。

    输出格式:

    输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出-11,表示需要建设更多公路。

    输入样例:

    6 15
    1 2 5
    1 3 3
    1 4 7
    1 5 4
    1 6 2
    2 3 4
    2 4 6
    2 5 2
    2 6 6
    3 4 6
    3 5 1
    3 6 1
    4 5 10
    4 6 8
    5 6 3
    

    输出样例:

    12

    此题考查最小生成树
    /*
    评测结果
    时间	结果	得分	题目	编译器	用时(ms)	内存(MB)	用户
    2017-07-05 09:16	答案正确	30	5-10	gcc	36	1	
    测试点结果
    测试点	结果	得分/满分	用时(ms)	内存(MB)
    测试点1	答案正确	15/15	1	1
    测试点2	答案正确	2/2	17	1
    测试点3	答案正确	2/2	1	1
    测试点4	答案正确	5/5	36	1
    测试点5	答案正确	6/6	21	1
    */
    #include<stdio.h>
    #include<stdlib.h>
    #define TRUE 1
    #define FALSE 0
    #define MAXN 1000
    #define INFINITY 100000
    #define ERROR -1
    typedef struct Edge* pEdge;
    struct Edge
    {
    	pEdge next;
    	int v;
    	int cost;
    };
    
    struct Vertex
    {
    	pEdge head;
    	int collectedFlag;
    	int totalCost;
    	int from;
    } gVertexTable[MAXN];
    
    void InitVertex() //初始化顶点列表
    {
    	int i;
    	for(i=0;i<MAXN;i++)
    	{
    		gVertexTable[i].head=NULL;
    		gVertexTable[i].collectedFlag=FALSE;
    		gVertexTable[i].from=0;
    		gVertexTable[i].totalCost=INFINITY;
    	}
    }
    
    pEdge CreateEdge() //创建新的边节点
    {
    	pEdge E;
    	E=malloc(sizeof(struct Edge));
    	E->next=NULL;
    	return E;
    }
    
    void InsertEdge(int a,int b,int cost) //插入边
    {
    	pEdge E=CreateEdge();
    	E->v=b;
    	E->cost=cost;
    	E->next=gVertexTable[a].head;
    	gVertexTable[a].head=E;
    }
    
    int FindAnyVertex(int N) //随便选一个有边的点当起点
    {
    	int i,tmp;
    	for(i=0;i<N;i++)
    	{
    		if(gVertexTable[i].head!=NULL)
    			return i;
    	}
    }
    
    int FindNextVertex(int N) //找下一个离收录集合最近的点
    {
    	int i;
    	int minCost=INFINITY;
    	int minIDX=-1;
    	for(i=0;i<N;i++)
    	{
    		if(gVertexTable[i].collectedFlag==FALSE && gVertexTable[i].totalCost<minCost)
    		{
    			minIDX=i;
    			minCost=gVertexTable[i].totalCost;
    		}
    	}
    	return minIDX;
    }
    
    void FindMinCost(int N)
    {
    	int i,k;
    	int sumCost=0;
    	pEdge tempE;
    	while((i=FindNextVertex(N))!= ERROR) //最外层,找一个集合外的,离集合距离最近的点
    	{
    		sumCost+=gVertexTable[i].totalCost; //把这个点收入集合,边长累加
    		gVertexTable[i].collectedFlag=TRUE;
    		gVertexTable[i].totalCost=0;
    
    		for(k=0;k<N;k++) //内层,遍历已在集合内的点
    		{
    			if(gVertexTable[k].collectedFlag==FALSE)
    				continue;
    			tempE=gVertexTable[k].head;
    			while(tempE!=NULL) //遍历集合内的点的每条边,计算到集合外的距离
    			{
    				if(gVertexTable[tempE->v].totalCost>gVertexTable[i].totalCost+tempE->cost)
    				{
    					gVertexTable[tempE->v].totalCost=gVertexTable[i].totalCost+tempE->cost;
    //					printf("%d->%d |tempE->cost=%d
    ",i,tempE->v,tempE->cost);
    					gVertexTable[tempE->v].from=i;
    				}
    				tempE=tempE->next;
    			}
    		}
    	}
    	
    	for(i=0;i<N;i++) 
    	{
    		if(gVertexTable[i].collectedFlag==FALSE)//如果有点没被收进来,说明整个图没有完全连通
    		{
    			printf("-1");
    			return;
    		}
    	}
    	
    	printf("%d",sumCost); //输出最小生成树的长度
    }
    
    int main()
    {
    	int N,M;
    	int i,v1,v2,cost,startVertex;
    	InitVertex();
    	scanf("%d %d",&N,&M);
    	for(i=0;i<M;i++)
    	{
    		scanf("%d %d %d",&v1,&v2,&cost);
    		InsertEdge(v1-1,v2-1,cost);//输入的值范围是1-N,减1换算成下标范围
    		InsertEdge(v2-1,v1-1,cost);
    	}
    	startVertex=FindAnyVertex(N); //随便找个非空节点当起点
    	gVertexTable[startVertex].totalCost=0;//距离置零,方便在第一次搜索中找到。
    	gVertexTable[startVertex].from=startVertex;
    	FindMinCost(N);
    }
    

      

  • 相关阅读:
    或许你不知道的10条SQL技巧
    windows7下php5.4成功安装imageMagick,及解决php imagick常见错误问题。(phpinfo中显示不出来是因为:1.imagick软件本身、php本身、php扩展三方版本要一致,2.需要把CORE_RL_*.dll多个文件放到/php/目录下面)
    如何循序渐进、有效地学习JavaScript?
    php数组学习记录01
    安装laravel框架
    数据库水平切分的实现原理解析——分库,分表,主从,集群,负载均衡器(转)
    PHP 获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
    找回了当年一篇V4L2 linux 摄像头驱动的博客
    Selective Acknowledgment 选项 浅析 2
    Selective Acknowledgment 选项 浅析 1
  • 原文地址:https://www.cnblogs.com/gk2017/p/7141087.html
Copyright © 2011-2022 走看看