Kattis - doubleclique (图论)
2024-09-29 19:18:42
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 = *1e5 + ;
const LL M = 1e9+; int d[maxn], sum[maxn]; int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
d[x]++, d[y]++;
}
sort(d+, d++n);
reverse(d+, d++n); for (int i = ; i <= n; i++)
sum[i] = sum[i-] + d[i]; LL ans = ;
int mid = ;
for (int i = ; i <= n; i++)
if (1ll*i*(i-)+sum[n]-sum[i] == sum[i])
{
ans++;
mid = i;
break;
} //找到一种可行方案。
//团中的点的度数一定大于等于独立集中的点的度数,所以排个序直接枚举断点即可。 if (!ans)
{
printf("0\n");
return ;
}
for (int i = ; i <= mid; i++)
if (1ll*(mid-)*(mid-)+sum[n]-sum[mid]+d[i] == sum[mid]-d[i]) ans++;
for (int i = mid+; i <= n; i++)
if (1ll*(mid+)*mid+sum[n]-sum[mid]-d[i] == sum[mid]+d[i]) ans++; LL x = , y = ;
for (int i = ; i <=mid; i++)
if (d[i] == d[mid]) x++;
for (int i = mid+; i <= n; i++)
if (d[i] == d[mid]) y++; ans = (ans+x*y)%M;
printf("%lld", ans);
}
最新文章
- 【问题解决】线程间操作无效:从不是创建控件“textBox1”的线程访问它
- 线程池ThreadPool的初探
- Zygote进程【3】——SystemServer的诞生
- yield return 和 yield break
- Thread create 创建进程
- JS概念
- Notification封装(没做从网络下载)
- POJ3080:Blue Jeans
- Cocos2d-x 3.1.1 学习日志6--30分钟了解C++11新特性
- 转载 C#文件上传
- ubuntu 自动获取ip的怎么设置
- 二维坐标点排序(JavaScript)
- SNMP相关的RFC建议和链接
- 升级 pip 超时解决方案
- Python数据可视化-seaborn库之countplot
- java基础知识—字符串
- maven私库nexus2.3.0-04迁移升级到nexus-3.16.1-02(异机迁移备份)
- GCC编译器原理(二)------编译原理一:ELF文件(2)
- js题目小记
- WPF编程,TextBlock中的文字修饰线(上划线,中划线,基线与下划线)的使用方法。