人活着系列之Streetlights
题目描述
人活着如果是为了家庭,亲情----可以说是在这个世界上最温暖人心的,也是最让人放不下的,也是我在思索这个问题最说服自己接受的答案。对,也许活着是一种责任,为了繁殖下一代,为了孝敬父母,男人要养家糊口,女人要生儿育女,就这样循环的过下去,但最终呢?还是劳苦愁烦,转眼成空呀!
为了响应政府节约能源的政策,某市要对路灯进行改革,已知该市有n个城镇,有m条道路,改革后该市只开一部分道路的路灯,而且要使任意两个城镇之间有路灯开着。城镇编号为0~n-1;每条道路开的路灯要花费一定的费用,求改革后最多能节省多少费用。
输入
多组输入,每组第一行输入n, m(1≤n≤ 100000,n-1≤m ≤100000);接下来m行,每行3个数u, v, w;代表城镇u到城镇v开着路灯的花费为w。
输出
输出改革后最多能节省的费用,如果数据不能保证任意两个城镇有路灯开着,输出-1。
示例输入
3 3 0 1 1 1 2 5 0 2 2 4 3 0 1 1 1 2 3 0 2 4
示例输出
5 -1
Kruskal + 压缩路径 的模板
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
int n,m;
int bin[1000000];
struct node
{
int u,v,w;
} q[1000010];
int cmp (const void *a,const void *b)
{
return (*(struct node *)a).w -(*(struct node *)b).w;
}
int findd(int x)
{
int k, j, r;
r = x;
while(r != bin[r])
r = bin[r];
k = x;
while(k != r)
{
j = bin[k];
bin[k] = r;
k = j;
}
return r;
}
int Kruskal ( )
{
int ans =0;
for (int i =0 ; i < m; i++)
{
int xx= findd (q[i].u);
int yy = findd (q[i].v);
if (xx != yy)
{
bin[xx] = yy;
ans += q[i].w;
}
}
return ans;
}
int main ()
{
while (~scanf ("%d%d",&n,&m))
{
int sum =0;
for (int i = 0 ; i <= n; i++)
{
bin[i] = i;
}
for (int i =0 ; i < m ; i++)
{
scanf ("%d%d%d",&q[i].u,&q[i].v,&q[i].w);
sum += q[i].w;
}
qsort (q,m,sizeof (q[0]),cmp);
int ans = Kruskal();
int flag = 1;
int pp = findd (1);
for (int i = 0; i < n; i++)
{
if (pp != findd(i))
{
flag = 0;
break;
}
}
if (flag == 1)
printf ("%d\n",sum - ans);
else printf ("-1\n");
}
return 0;
}
/**************************************
Problem id : SDUT OJ 2933
User name : Caesar
Result : Accepted
Take Memory : 4048K
Take Time : 200MS
Submit Time : 2014-08-03 14:18:09
**************************************/