hdu 3371(Connect the Cities)(最小生成树)

Connect the Cities

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 10692    Accepted Submission(s): 3037

Problem Description

In 2100, since the sea level rise, most of the cities disappear. Though some survived cities are still connected with others, but most of them become disconnected. The government wants to build some roads to connect all of these cities
again, but they don’t want to take too much money.

Input

The first line contains the number of test cases.

Each test case starts with three integers: n, m and k. n (3 <= n <=500) stands for the number of survived cities, m (0 <= m <= 25000) stands for the number of roads you can choose to connect the cities and k (0 <= k <= 100) stands for the number of still connected
cities.

To make it easy, the cities are signed from 1 to n.

Then follow m lines, each contains three integers p, q and c (0 <= c <= 1000), means it takes c to connect p and q.

Then follow k lines, each line starts with an integer t (2 <= t <= n) stands for the number of this connected cities. Then t integers follow stands for the id of these cities.

Output

For each case, output the least money you need to take, if it’s impossible, just output -1.

Sample Input

1
6 4 3
1 4 2
2 6 1
2 3 5
3 4 33
2 1 2
2 1 3
3 4 5 6

Sample Output

1

Author

dandelion

Source

HDOJ Monthly Contest – 2010.04.04

考察知识点:

最小生成树。

题目难点:如何判断-1 出现的情况。怎么将已经连通的路径标记。

解决办法:出现-1 的情况,无非就是两条路之间没有连接,即距离无法判断。那么在最小生成树中的prime算法中,可以通过比较确定一个顶点的最小值,来判断是否有孤立的点(即既无法构建道路,也没有与其他顶点相连接的路径),要是有的话,就说明没有无法连通,满足-1出现的情况。对已经连通的路径可以通过将其权值赋值为0,来进行标记,在选择最小权值 的时候,就会将其他的路径略去。

代码如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int map[550][550];
int visit[550];
int n;
void prime()
{
	int i,j,sum=0,min,k;
	memset(visit,0,sizeof(visit));
	visit[1]=1;
	for(i=1;i<n;i++)//共需要构建n-1条边,所以共要循环n-1次
	{
		min=1000;
		for(j=1;j<=n;j++)//n个顶点
		{
			if(!visit[j]&&min>map[1][j])
			{
				min=map[1][j];
				k=j;
			}
		}
		if(min==1000)//要是有连通的边则min就会发生相应的变化
		{
			break;
		}
		sum+=min;
		visit[k]=1;
		for(j=1;j<=n;j++)
		{
			if(!visit[j]&&map[1][j]>map[k][j])
			map[1][j]=map[k][j];
		}
	}
	if(min==1000)
	printf("-1\n");
	else
	printf("%d\n",sum);
}
int main()
{
	int num,m,k,p,q,c,t,i,j,a,b;
	scanf("%d",&num);
	while(num--)
	{
		//memset(map,1000,sizeof(map));//memset函数看来是有范围的只能对数组进行1,或者是0,的赋值,其他则没有办法赋值。
		scanf("%d%d%d",&n,&m,&k);
		for(i=1;i<=n;i++)//数组初始化
		{
			for(j=1;j<=n;j++)
			{
				map[i][j]=1000;
			}
		}
		for(i=0;i<m;i++)
		{
			scanf("%d%d%d",&p,&q,&c);//注意需要考虑重边的情况。
			map[p][q]=map[p][q]>c?c:map[p][q];
			map[q][p]=map[p][q];
		}
		for(i=0;i<k;i++)
		{
			scanf("%d%d",&t,&a);
			for(j=t-1;j>0;j--)
			{
				scanf("%d",&b);
				map[a][b]=map[b][a]=0;
			}
		}
		prime();
	}
	return 0;
}
时间: 2024-11-02 03:41:23

hdu 3371(Connect the Cities)(最小生成树)的相关文章

hdu 3371 Connect the Cities (最小生成树Prim)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3371 题目不难 稍微注意一下 要把已经建好的城市之间的花费定义为0,在用普通Prim算法就可以了:我没有用克鲁斯卡尔算法(Kruskal's algorithm),因为这题数据比较大,而且要处理大量的数据使它为0,怕超时T^T..... 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 5 usi

hdu 3371 Connect the Cities 最小生成树

#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <string> #include <ma

hdu 3371 Connect the Cities

链接:hdu 3371 已知已连通的路的序号,以及未连通的路的费用,求将所有城市连通的最小费用 也是将已连通的路的费用记为0,就转化成了基本最小生成树的题 不过这题数组要开的大点,不然很容易就RE了... #include<cstdio> #include<algorithm> using namespace std; int f[510],n,m; struct stu { int a,b,c; }t[100000]; int cmp(struct stu x,struct st

hdu 3371 Connect the Cities(prim算法)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3371 Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 13628    Accepted Submission(s): 3679 Problem Description In 2100, since

HDU 3371 Connect the Cities 【最小生成树,Prime算法+Kruskal算法】

Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17167    Accepted Submission(s): 4335 Problem Description In 2100, since the sea level rise, most of the cities disappear. Tho

hdu 3371 Connect the Cities Prim + Kruskal两种算法分别AC 水过~~~~

Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11727    Accepted Submission(s): 3278 Problem Description In 2100, since the sea level rise, most of the cities disappear. Tho

Hdu 3371 Connect the Cities(最小生成树)

地址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 其实就是最小生成树,但是这其中有值得注意的地方:就是重边.题目没有告诉你两个城市之间只有一条路可走,所以两个城市之间可能有多条路可以走. 举例: 输入可以包含 1 2 3  // 1到2的成本为3   1 2 5  //1到2的成本为5      因此此时应选成本较低的路. 然后,已经连通的城市之间的连通成本为0. 这题用G++提交得到984ms的反馈,用C++提交则得到484ms的反馈. 很想知

HDU 3371 Connect the Cities(并查集+Kruskal)

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 思路: 这道题很明显是一道最小生成树的题目,有点意思的是,它事先已经让几个点联通了.正是因为它先联通了几个点,所以为了判断连通性 很容易想到用并查集+kruskal. 不过要注意 这题有一个坑点,就是边数很多 上限是25000,排序的话可能就超时了.而点数则比较少 上限是500,所以很多人选择用Prim做.但我个人觉得这样连通性不好判断.其实边数多没关系,我们主要去重就好啦,用邻接矩阵存下两点

POJ:3371 Connect the Cities(最小生成树)

http://acm.hdu.edu.cn/showproblem.php?pid=3371 AC代码: /** /*@author Victor /* C++ */ #include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string

hdu oj 3371 Connect the Cities (最小生成树)

Connect the Cities Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9985    Accepted Submission(s): 2843 Problem Description In 2100, since the sea level rise, most of the cities disappear. Thou