zoukankan      html  css  js  c++  java
  • 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; }
  • 相关阅读:
    上周热点回顾(12.1212.18)
    上周热点回顾(11.2111.27)
    上周热点回顾(11.1411.20)
    博客园电子期刊2011年11月刊发布啦
    “CDN加速”测试
    上周热点回顾(11.2812.4)
    上周热点回顾(12.1912.25)
    上周热点回顾(12.512.11)
    提醒:安装MS11100 .NET Framework高危漏洞补丁一定要所有服务器一起安装
    郑州公积金
  • 原文地址:https://www.cnblogs.com/lusiqi/p/11607669.html
Copyright © 2011-2022 走看看