数三角形
题目描述
刚刚上高中的洁洁在学习组合数学的过程中遇到一道麻烦的题目,她希望你能帮助她解决。给定一张无向完全图 G,其中大部分边被染成蓝色,但也有一些边被染成红色或者绿色。现在,洁洁需要给这张图的多样性进行打分。一张图的多样性取决于它的同色和异色三角形的个数。具体来说,G中每有一个三边颜色都互不同的三角形(异色三角形)可以得 3分,每有一个三边颜色都相同的三角形(同色三角形)则要被扣掉 6分,其它三角形不得分也不扣分。
现在,请你写一个程序来计算 G 的多样性分数。
输入格式
第一行两个正整数 n 和 m,其中 n 表示 G 中顶点的个数,m 表示 G 中红色或者绿色的边的条数。
接下来 m 行每行包括三个整数 a,b,c,代表连接顶点 a和顶点 b 的边颜色为红色 (c=1)或者绿色 (c=2)。
输出格式
一行,G 的多样性得分。
数据范围与约定
对于 20% 的数据,n≤500,m≤n(n−1)2n≤500,m≤2n(n−1)
对于 40% 的数据,n≤2000,m≤n(n−1)2n≤2000,m≤2n(n−1)
对于100% 的数据,n≤100000,m≤min(n(n−1)2,200000),n≤100000,m≤min(2n(n−1),200000)。
样例解释 1
(1, 2, 3)(1,2,3) 能组成一个同色三角形,找不到异色三角形,得分为 -6。
样例解释 2
(1, 2, 3)(1,2,3) 能组成一个同色三角形,(1,2,4),(1,3,4)(1,2,4),(1,3,4) 能组成两个异色三角形,得分为 2*3-6=0。
样例输入1
4 3
1 2 1
1 3 1
2 3 1
样例输出1
-6
样例输入2
4 4
1 2 1
1 3 1
2 3 1
1 4 2
样例输出2
0
题目太具有迷惑性了。考试时给的时限是2s,但是实际上算法是O(N)级别的。而且很容易想到组合数之类的东西。
这道题其实是构造出来的,不具有一般性。
如果对组合数学中的染色问题有所了解,那么应该从异色角的方面考虑。设异色角的个数为Same,同色角的个数为Dif。并将完全图中的三角形分成三类:
A.三条边异色的三角形
B.三条边中两条边颜色相同的三角形
C.三条边颜色相同的三角形
那么显然有以下关系式:
Same=B+3C …………①
Dif=3A+2B …………②
注意到答案实际上等于3A−6C,也就是②−2①。那么只要求出同色角和异色角的个数就可以了。这是很容易实现的。
由此也可以看出,如果加分扣分之比不是1:2的话,就无法用这个方法做出来了。
#include<stdio.h>
#define ll long long
#define MAXN 100005
ll Cnt[MAXN][3],Ans,Same,Dif;
int N,M;
int main()
{
int i,j,x,y,z;
scanf("%d%d",&N,&M);
for(i=1;i<=M;i++)
{
scanf("%d%d%d",&x,&y,&z);
Cnt[x][z]++;Cnt[y][z]++;
}
for(i=1;i<=N;i++)
{
Cnt[i][0]=N-1-Cnt[i][1]-Cnt[i][2];
for(j=0;j<3;j++)Same+=Cnt[i][j]*(Cnt[i][j]-1)/2;
Dif+=Cnt[i][0]*Cnt[i][1]+Cnt[i][1]*Cnt[i][2]+Cnt[i][0]*Cnt[i][2];
}
Ans=Dif-2*Same;
printf("%lld",Ans);
}