加油 ( •̀ ω •́ )y!

组合数学 单色三角形,,(排列组合+容斥原理)

  题目:空间里有n个点,任意三点不共线。每两个点之间都用红色或者黑色线段链接。如果

一个三角形的三条边同色,则这个三角形是单色三角形。对于给定的红色线段列表,

找出单色三角形的个数。

 

  分析:由于三角形总数C(n,3),所以求出异色三角形个数就求出了同色三角形个数。用暴力

枚举的方法,我们将遍历所有的三角形,时间复杂度为O(n^3),则必定超时。而经过推敲,我们会

发现这样的对应关系,一个异色三角形存在两个顶点,在该三角形中与它们相邻的两边是不同色

的;而对从一个顶点出发的两条异色边都属于一个异色三角形。这是个一对二的关系。设第i个点

连接了ai条红边、n-1-ai条黑边,这些边一定属于ai(n-1-ai)个不同的异色三角形。由于异色三角形

都会被考虑两次,所以最终的答案为ans/2。这个思想只需要从第一个顶点遍历到最后一个顶点,

所以时间复杂度是O(n)。

 

 

 1 #include<iostream>
 2 #include<vector>
 3 
 4 using namespace std;
 5 const int maxn = 10000;
 6 int n, m, T;
 7 long long ans;
 8 vector<int>s[maxn];
 9 int main()
10 {
11     ios::sync_with_stdio(false);
12     cin >> T;
13     while (T--)
14     {
15         s->clear();
16         cin >> n >> m;
17         for (int i = 1; i <= m; i++)
18         {
19             int a, b;
20             cin >> a >> b;
21             s[a].push_back(b);
22             s[b].push_back(a);
23         }
24         for (int i = 1; i <= n; i++)
25             ans += (n - 1 - s[i].size())*s[i].size();
26         ans /= 2;
27         cout << (n*(n - 1)*(n - 2)) / 6 - ans << endl;
28     }
29     return 0;
30 }

 

posted @ 2017-08-21 15:20  皮皮虎  阅读(1702)  评论(0编辑  收藏  举报