码迷,mamicode.com
首页 > 其他好文 > 详细

Kattis - doubleclique (图论)

时间:2018-08-21 11:37:04      阅读:392      评论:0      收藏:0      [点我收藏+]

标签:rom   并且   nbsp   部分   rev   bre   min   lan   cli   

From : North American Invitational Programming Contest 2018

 

给你一个图,以及它的补图。如果部分点在原图中是团,并且其他的所有点在补图中也是团,那么就叫做一个双团。

要求计算图中双团的数量。

 

 

 

这篇博客使我理解了这个问题:zro  https://www.cnblogs.com/clrs97/p/8730429.html  orz

 

如果其他点在补图中构成团,那么这些点在原图中是一个独立集。

可以想到,满足条件的状态是 (团的点数) × (团的点数 - 1) + 独立集点的度数和 =  团点的度数和。

因为 (团的点数) × (团的点数 - 1) = 团中所有边构成的度数,所以剩下的度数就是团的点 与 独立集的点之间的边所构成的度数了。

这样我们可以找出一种可行方案。

 

那么剩下的方案,可能是

1:团中一个点加入到独立集中:

2:也可能是独立集中一个点加入到团中

3:1+2

分别统计答案即可。

 

 

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 2*1e5 + 10;
const LL M = 1e9+7;

int d[maxn], sum[maxn];


int main()
{
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++)
        {
                int x, y;
                scanf("%d%d", &x, &y);
                d[x]++, d[y]++;
        }
        sort(d+1, d+1+n);
        reverse(d+1, d+1+n);

        for (int i = 1; i <= n; i++)
                sum[i] = sum[i-1] + d[i];

        LL ans = 0;
        int mid = 0;
        for (int i = 0; i <= n; i++)
                if (1ll*i*(i-1)+sum[n]-sum[i] == sum[i])
                {
                        ans++;
                        mid = i;
                        break;
                }
                
        //找到一种可行方案。
        //团中的点的度数一定大于等于独立集中的点的度数,所以排个序直接枚举断点即可。

        if (!ans)
        {
                printf("0\n");
                return 0;
        }
        for (int i = 1; i <= mid; i++)
                if (1ll*(mid-1)*(mid-2)+sum[n]-sum[mid]+d[i] == sum[mid]-d[i]) ans++;
        for (int i = mid+1; i <= n; i++)
                if (1ll*(mid+1)*mid+sum[n]-sum[mid]-d[i] == sum[mid]+d[i]) ans++;

        LL x = 0, y = 0;
        for (int i = 1; i <=mid; i++)
                if (d[i] == d[mid]) x++;
        for (int i = mid+1; i <= n; i++)
                if (d[i] == d[mid]) y++;

        ans = (ans+x*y)%M;
        printf("%lld", ans);
}

 

Kattis - doubleclique (图论)

标签:rom   并且   nbsp   部分   rev   bre   min   lan   cli   

原文地址:https://www.cnblogs.com/ruthank/p/9510168.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!