LightOJ 1029-Civil and Evil Engineer(最小/大生成树)

Description

A Civil Engineer is given a task to connect n houses with the main electric power station directly or indirectly. The Govt has given him permission to connect exactly n wires to connect all of them. Each of the wires connects
either two houses, or a house and the power station. The costs for connecting each of the wires are given.

Since the Civil Engineer is clever enough and tries to make some profit, he made a plan. His plan is to find the best possible connection scheme and the worst possible connection scheme. Then he will report the average of the costs.

Now you are given the task to check whether the Civil Engineer is evil or not. That‘s why you want to calculate the average before he reports to the Govt.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case contains a blank line and an integer n (1 ≤ n ≤ 100) denoting the number of houses. You can assume that the houses are numbered from 1 to n and the power station is numbered 0.
Each of the next lines will contain three integers in the form u v w (0 ≤ u, v ≤ n, 0 < w ≤ 10000, u ≠ v) meaning that you can connect u and v with a wire and the cost will be w. A line containing
three zeroes denotes the end of the case. You may safely assume that the data is given such that it will always be possible to connect all of them. You may also assume that there will not be more than 12000 lines for a case.

Output

For each case, print the case number and the average as described. If the average is not an integer then print it inp/q form. Where p is the numerator of the result and q is the denominator of the result; p and q are
relatively-prime. Otherwise print the integer average.

Sample Input

3

1

0 1 10

0 1 20

0 0 0

3

0 1 99

0 2 10

1 2 30

2 3 30

0 0 0

2

0 1 10

0 2 5

0 0 0

Sample Output

Case 1: 15

Case 2: 229/2

Case 3: 15

kruskal水过,题意;给一些连通的路,求最大生成树和最小生成树的和的一半,若是整数,直接输入,否则以分数模式输出。一开始求的时候大小两棵生成树用的同一个并查集,无限wa。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#define L long long
using namespace std;
const int INF=1<<27;
const int maxn=200010;
int n,v[maxn],u[maxn],w[maxn],fa[maxn],eg[maxn],fa1[maxn];
bool cmp(int x,int y)
{
	return w[x]<w[y];
}
bool cmp1(int x,int y)
{
	return w[x]>w[y];
}
void Make_set()
{
	for(int i=0;i<=n;i++)
		fa[i]=i;
}
void Make_set1()
{
	for(int i=0;i<=n;i++)
		fa1[i]=i;
}
int Find(int x)
{
	return x==fa[x]?x:fa[x]=Find(fa[x]);
}
int Find1(int x)
{
	return x==fa1[x]?x:fa1[x]=Find1(fa1[x]);
}
int Kruskal(int m)
{
	int i,ans=0;
	Make_set();
	for(i=0;i<m;i++)
	  eg[i]=i;
	sort(eg,eg+m,cmp);
	for(i=0;i<m;i++)
	{
		int e=eg[i];
		int fx=Find(u[e]);
		int fy=Find(v[e]);
		if(fx!=fy)
		{
			fa[fx]=fy;
			ans+=w[e];
		}
	}
		return ans;
}
int Big_Kruskal(int m)
{
	int i,ans=0;
	Make_set1();
	for(i=0;i<m;i++)
	  eg[i]=i;
	sort(eg,eg+m,cmp1);
	for(i=0;i<m;i++)
	{
		int e=eg[i];
		int fx=Find1(u[e]);
		int fy=Find1(v[e]);
		if(fx!=fy)
		{
			fa1[fx]=fy;
			ans+=w[e];
		}
	}
		return ans;
}
int main()
{
	int T;
	scanf("%d",&T);
	for(int cas=1;cas<=T;cas++)
	{
		scanf("%d",&n);
		int i=0;
		while(cin>>u[i]>>v[i]>>w[i])
		{
			if(!u[i]&&!v[i]&&!w[i])
				break;
			i++;
		}
		//cout<<i<<endl;
		int a=Kruskal(i),b=Big_Kruskal(i);
		printf("Case %d: ",cas);
		if((a+b)%2==0)
			printf("%d\n",(a+b)/2);
		else
			printf("%d/2\n",a+b);
	}
	return 0;
}
时间: 2024-07-30 09:02:05

LightOJ 1029-Civil and Evil Engineer(最小/大生成树)的相关文章

Lightoj 1029 - Civil and Evil Engineer

1029 - Civil and Evil Engineer    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB A Civil Engineer is given a task to connect n houses with the main electric power station directly or indirectly. The Govt has given him perm

LightOJ 1029 Civil and Evil Engineer最小生成树和最大生成树

F - Civil and Evil Engineer Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice LightOJ 1029 Description A Civil Engineer is given a task to connect n houses with the main electric power station directly

Light OJ 1029- Civil and Evil Engineer (图论-最小生成树)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1029 题目大意:一个发电站,给n座房子供电, 任意房子之间有电线直接或者间接相连接, 现在想知道需要连接这些房子花费的平均电线长度.平均电线长度 = (最长电线长度 + 最短电线长度)/ 2: 解题思路:裸的最小生成树 代码如下: #include <bits/stdc++.h> using namespace std; const int N = 1003; struct

lightoj 1029 最小生成树 + 最大生成树

题意,给出若干条连接两个屋子间的路线的价格(保证一定都能联通),问联通所有屋子的最大代价和最小代价的平均值为多少. 分析,即求一次最大生成树,一次最小生成树 1 /* When all else is lost the future still remains. */ 2 #define rep(X,Y,Z) for(int X=(Y);X<(Z);X++) 3 #define drep(X,Y,Z) for(int X=(Y);X>=(Z);X--) 4 #define fi first 5

最小生成树应用

1.求类似最小距离最大值/最大距离最小值问题,通过最小/大生成树固定一个条件,另一个条件在树里找到. 例题:货车运输. 求两点间的一条路径,使得最小边权最大.先通过最大生成树确定最大,再从两点间的边里选择最小的边权,用到了lca. 例题:Star Way to Heaven 求路径到一些星星的最小距离的最大值.这个跟上边的不同点是用的是最小生成树,用prim算法找到所有星星以及边界的最小生成树,最大两边界之间的边权的最大值就是答案. 但我们关注的是为什么最小生成树可以接受.因为这两道题虽然题面大

LightOJ 1380 – Teleport 【最小树形图】

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1380 最小树形图也就是有向图的最小生成树.普通的prim无法求解. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <queue> using names

图——图的Prim法最小生成树实现

1,运营商的挑战: 1,在下图标出的城市间架设一条通信线路: 2,要求: 1,任意两个城市间都能够通信: 2,将架设成本降至最低: 2,问题抽象: 1,如何在图中选择 n - 1 条边使得 n 个顶点间两两可达,并且这 n - 1 条边的权值之和最小? 3,最小(大)生成树: 1,仅使用图中的 n - 1 条边连接图中的 n 个顶点: 2,不能使用产生回路的边: 3,各边上的权值总和达到最小(大): 4,寻找最小生成树: 5,使用 prim 方法手工寻找最小生成树: 6,最小生成树算法步骤(pr

图——图的Kruskal法最小生成树实现

1,最小生成树的特征: 1,选取的边是图中权值较小的边: 2,所有边连接后不构成回路: 2,prim 算法是以顶点为核心的,最下生成树最大的特征是边,但 prim 算法非要以顶点为核心来进行,有些复杂和难以理解: 3,既然最小生成树关心的是如何选择 n - 1 条边,那么是否可以直接以边为核心进行算法设计? 4,简单尝试: 1,由 4 个顶点构成的图,选择 3 条权值最小的边: 2,还要设法避免回路: 5,需要解决的问题: 1,如何判断新选择的边与已选择的边是否构成回路? 6,技巧:前驱标记数组

0618图的整理

第五章  图 5.1      医院设置 codevs 2577:http://codevs.cn/problem/2577/ 源程序名            hospital.???(pas, c, cpp) 可执行文件名        hospital.exe 输入文件名          hospital.in 输出文件名          hospital.out [问题描述] 设有一棵二叉树,如图5-1: 131 /   \ 24  123 /  \ 420 405 其中,圈中的数字表