60.同色三角形 (15分)

C时间限制:3000 毫秒 |  C内存限制:3000 Kb
题目内容:
平面上有n个点(n≤8000),每两个点之间都有一条红色或者是黑色的线段,任意三点均不共线。
现在,已知哪些点之间连的线段是红色的,剩下的线段都是黑色的,要求计算这些点组成的三角
形中有多少是同色的(顶点编号从1到n)?
输入描述
第一行是n, m(3≤n≤8000),n表示点的个数,m表示红色线段的条数。下面m行,每
一行都是两个整数a和b,表示点a和点b之间的线段是红色的(a<b)。
输出描述
只有一行,表示同色三角形的个数。
提示:本题输出数据可能会超出长整数(long int)的范围。
输入样例
6 5
1 2
1 3
2 3
2 5
3 6


 

思路

  这道题应该反着想,但是我就看着题目同色三角形,于是就想如何查找同色,自己傻了,同色三角形的个数 = 总三角形的个数 - 异色三角形的个数

总三角形的个数就是在n各点中取3个点,就是n*(n-1)*(n-2)/(1*2*3)

异色三角形就是先固定一个点m(for循环遍历每个点)然后vector中v[m]中存储了与点m相邻的点,然后n-v[m]-1存储的是与m点不相邻的点,

于是就可以求了。

 


 

代码:

#include<iostream>
#include<stdio.h>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 8e3+10;
ll sum = 0;
vector<int> v[maxn];
int main(){
    int n,m;
    cin>>n>>m;
    int a,b;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        sum+=(v[i].size()*(n-v[i].size()-1));
    }
    cout<<n*(n-1)*(n-2)/6-sum/2<<endl;//sum/2是因为是一条边加一个点组成三角形,而边中的两个点是重复算了两次的,所以要/2
return 0; }

 

posted @ 2019-09-29 14:25  sqsq  阅读(307)  评论(0编辑  收藏  举报