zznu 1914 asd的甩锅计划
http://acm.zznu.edu.cn/problem.php?id=1914
asd的甩锅计划
时间限制: 1 Sec 内存限制: 128 MB提交: 114 解决: 10
[提交][状态]
题目描述
大家对hdu上面的畅通工程系列一定很熟悉了吧。比如如下一段,就是畅通工程里面其中一个题的叙述。
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
大家觉得这种情况一定很简单而且生活中遇不到吧。然而你错了!NBUT的书记yh就遇到了这么个头疼事:asd下达命令让村长去把村里的路修的高端大气上档次,简单说就是重新建路,可是村长又甩手把这事给了yh书记。然而现在一个大问题是:经费不够用!因此yh书记觉得不可能每家每户都有一条道路通往村里任意一家,只要能走到就行了(不管是直接到达还是先经过别人家这样的间接到达)。
NBUT是个有名的“坑”地方,不是地方坑,而是地方有坑,这样的话在那些有坑的地方修路和在平地上修路的价钱当然不一样啦。更坑的是,村长已经划好一些可能要修的路线了,你只能在这些线路上面选一些来修。比如说,尽管村长要修的路连着张三丰和李四收,这条路会经过一些坑,但是你决定修这条路的话不能绕过它,只能去填平,经费当然不一样啦,当然你也可以选择不去修这条路,只要能让村子里每户人家能相互到达就可以了。
现在yh书记已经知道村里有n户人家了,并且拿到村长给他的平面设计图,上面标明哪些路要修多长,和修这条路的费用,现在书记来请教你,完成镇里的任务最少需要修多长的路,和最少要花多少钱。书记是个爱民的人,希望村民能省力就省力,所以多花一些钱修更短的路是无所谓的,但是能完成这个任务当然还是能省钱就省钱。另外村长图里的起点终点相同的两条路是认为不一样的,可能按路线1建路比路线2减更短更省钱,谁知道呢~所以若是按照村长的图不能完成村里的任务,那么就输出“村长你家铺子烧啦”。
输入
每行两个整数n(1 <= n <= 1000),m (1 <= m <= 2e6+7),分别表示村里有多少户人家,和村长给的图里面的路线。
接下来m行,每行四个整数 a, b, c, d(1 <= a, b <= n, 1 <= c <= 1000, 1 <= d <= 1e9+7),分别表示农民a家到b家建一条路的话,长度是c,花费是d。
输出
对于每组数据,如果能满足建路要求,那么每行输出两个整数 length, cost,分别表示一共要修路的长度,和修路的花费,具体如题意描述。否则输出“村长你家铺子烧啦”。
样例输入
2 1
1 2 3 4
样例输出
3 4
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> #include<ctype.h> #define INF 0x3f3f3f3f #define max(a, b)(a > b ? a : b) #define min(a, b)(a < b ? a : b) #define N 1010 struct st { int a, b, c; long long d; } node[2000010]; int n, m, f[N]; int Find(int x) { if(x != f[x]) f[x] = Find(f[x]); return f[x]; } int cmp(const void *a, const void *b) { struct st *s1 = (struct st *)a, *s2 = (struct st *)b; if(s1->c == s2->c) return s1->d - s2->d; return s1->c - s2->c; } int main() { int i, a, b, c, k, l, num, ra, rb; long long d, w; while(scanf("%d%d", &n, &m) != EOF) { l = w = k = 0; num = 1; for(i = 1 ; i<= n ; i++) f[i] = i; while(m--) { scanf("%d%d%d%lld", &a, &b, &c, &d); node[k].a = a; node[k].b = b; node[k].c = c; node[k].d = d; k++; } qsort(node, k, sizeof(node[0]), cmp); for(i = 0 ; i < k ; i++) { ra = Find(node[i].a); rb = Find(node[i].b); if(ra != rb) { l += node[i].c; w += node[i].d; num++; f[ra] = rb; } if(num == n) break; } if(num == n) printf("%d %lld\n", l, w); else printf("村长你家铺子烧啦\n"); } return 0; }