这是民大学长之前出的一次题目,感觉题目不错现在才写题解=
化简不难得到: sig(maxval[i]−minval[i])=sig(maxval)−sigma(minval)
如何求所有最大值和最小值呢,分别从大到小和从小到大排序利用并查集就行了,比较巧妙。
额==题目设了一些坑,一个是一个方向的并查集会爆栈,故手工开栈,另外一个是钥匙用unsigned long long==
1 #pragma comment(linker,"/STACK:16777216")
2 #include<stdio.h>
3 #include<string.h>
4 #include<algorithm>
5 using namespace std;
6 #define LL long long
7 #define uLL unsigned long long
8 struct dian{
9 uLL x,y,w;
10 }a[150005];
11 uLL father[150005],num[150005],n;
12 int cmp1(dian n1,dian n2)
13 {
14 return n1.w<n2.w;
15 }
16 int cmp2(dian n1,dian n2)
17 {
18 return n1.w>n2.w;
19 }
20 uLL find(uLL x)
21 {
22 if (x!=father[x]) father[x]=find(father[x]);
23 return father[x];
24 }
25 uLL work()
26 {
27 uLL ans=0,i,f1,f2;
28 for (i=1;i<=n;i++)
29 {
30 father[i]=i;
31 num[i]=1;
32 }
33 for (i=1;i<n;i++)
34 {
35 f1=find(a[i].x); f2=find(a[i].y);
36 ans+=num[f1]*num[f2]*a[i].w;
37 father[f1]=f2;
38 num[f2]+=num[f1];
39 }
40 return ans;
41 }
42 int main()
43 {
44 uLL t=0,ans1,ans2,i;
45 while (~scanf("%I64u",&n))
46 {
47 for (i=1;i<n;i++)
48 scanf("%I64u%I64u%I64u",&a[i].x,&a[i].y,&a[i].w);
49 sort(a+1,a+n,cmp1);
50 ans1=work();
51 sort(a+1,a+n,cmp2);
52 ans2=work();
53 printf("Case #%I64u: %I64u\n",++t,ans1-ans2);
54 }
55 return 0;
56 }
View Code
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5176
转载于:https://www.cnblogs.com/xiao-xin/articles/4307704.html