Havel-Hakimi定理问题
昨天模拟了一下13年长沙现场赛的题,刚开始不太好,第一题思维有点僵硬,做的有点慢。不过总共做了4题,还算不错,至少是稳铜了,何时能模拟到银呀!
第一个水题A是维护后缀最小值,不过要注意等于0的情况。
第二题J貌似是概率DP,ZY过得。
第三题C是几何,只要算出点到直线的距离再分类讨论一下即可。不过这里要注意直线根本不和那个圆相交的情况(往反方向走了)。
第四题K是搜索。关于魔方的搜索题。想来Y学长肯定很喜欢做的吧。这里是二阶魔方,它只需要有6种状态转移即可(因为,比如顺时针转第1面,和逆时针转与第1面相对的那一面是等价的,所以只需要6个面全部顺时针转即可)。所以可以有复杂度为O(6^7)。当然,还可以适当剪下枝,就是前一个状态第1面顺时针转了,当前状态,与第1面对应的那一面就不需要顺时针转了,因为那样的话就转化原来的状态了。最后是100ms过的。
现在补一下银牌题G。
当然,先补一下Havel-Hakimi定理。据说是离散数学里的知识,,好像没学过。。
Frogs’ Neighborhood
题目传送:POJ - 1659 - Frogs’ Neighborhood
分析:给出一个度序列,问这个序列是否可以构成图,而是否可以构成图根据
Havel-Hakimi定理的方法来构图
这个题还是在机房做的。。
以下为转载:
Havel-Hakimi定理:
1,一个非负整数组成的有限序列如果是某个无向图的度序列,则称该序列是可图的。2,判定过程:
(1)对当前数列排序,使其呈非递增序列
(2)从第二个数开始对其后d[1]个数字减1,d[1]代表排序后第1个数的值
(3)然后删除第一个之后对剩下的数继续排序
(4)一直循环直到当前序列出现负数(即不是可图的情况)或者当前序列全为0 (可图)时退出。3,举例:
序列S:7,7,4,3,3,3,2,1
删除序列S的首项 7 ,对其后的7项每项减1,
得到:6,3,2,2,2,1,0,
继续删除序列的首项6,
对其后的6项每项减1,
得到:2,1,1,1,0,-1,
到这一步出现了负数,因此该序列是不可图的再举例:
序列:4 3 1 5 4 2 1
排序之后:5 4 4 3 2 1 1
删除5对后面5个数减1操作
3 3 2 1 0 1
排序
3 3 2 1 1 0
删除3对后面3个数减1操作
2 1 0 1 0
排序
2 1 1 0 0
删除2 对后面2个数减1操作
0 0 0 0
全为0,可图
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;int n;struct node {int id;int x;bool operator < (const node& a) const {return x > a.x;}
}a[15];int mp[15][15];int main() {int T;scanf("%d", &T);while(T --) {memset(mp, 0, sizeof(mp));scanf("%d", &n);for(int i = 1; i <= n; i ++) {scanf("%d", &a[i].x);a[i].id = i;}int flag = 1;while(1) {sort(a + 1, a + n + 1);if(a[1].x <= 0) break;//for(int j = 1; j <= n;j ++) cout << a[j].id << " "; cout << endl; for(int j = 2; j <= a[1].x + 1 && flag; j ++) {mp[a[1].id][a[j].id] = 1;mp[a[j].id][a[1].id] = 1;a[j].x --;if(a[j].x < 0) {flag = 0;break;}}a[1].x = 0;}if(flag) {printf("YES\n");for(int i = 1; i <= n; i ++) {for(int j = 1; j < n; j ++) {printf("%d ", mp[i][j]);}printf("%d\n", mp[i][n]);}}else printf("NO\n");if(T > 0) printf("\n");}return 0;
}
Graph Reconstruction
题目传送:ZOJ - 3732 - Graph Reconstruction
13年长沙赛区银牌题。
分析:Havel-Hakimi定理
在了解Havel-Hakimi这个定理的基础上,花了40多分钟搞出来的,还算不错。不过得先知道这个定理。事实上这个定理就是贪心的过程。
其实这个题就是考得Havel-Hakimi定理。剩下的就很好办了,只需要考虑输出多解的情况就ok了。
为什么会有多解?因为有些边互换一下仍然可以构成图,且不影响度序列。
而只需要在Havel-Hakimi定理的过程中加一条判断即可,比如当前度数是5,要对后面5个度数都减去1,此时判断最后面一个度数和其后的一个度数是否相等,相等的话就说明可以交换,否则不行。
不过输出稍微有点复杂,因为是要输出一个类似关联矩阵的东西,这里为了方便,就用pair存了。
AC代码:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;int n;struct node {int id;int deg;bool operator < (const node& a) const {return deg > a.deg;}
}a[105], b[105];pair<int, int> ans1[10005];
int cnt1;
pair<int, int> ans2[10005];
int cnt2;int main() {while(scanf("%d", &n) != EOF) {int sum = 0;for(int i = 1; i <= n; i ++) {scanf("%d", &a[i].deg);sum += a[i].deg;a[i].id = i;b[i].deg = a[i].deg;b[i].id = i;}int flag = 1;//刚开始默认是UNIQUE的cnt1 = cnt2 = 0;while(1) {sort(a + 1, a + n + 1);if(a[1].deg <= 0) break;int m = a[1].deg + 1;if(a[m].deg == a[m + 1].deg) flag = 2;for(int i = 2; i <= m; i ++) {ans1[cnt1 ++] = make_pair(a[1].id, a[i].id);a[i].deg --;if(a[i].deg < 0) {flag = 0;break;}}a[1].deg = 0;}int ok = 0;//用于判断是否已经得到第二个图if(flag == 2) while(1) {sort(b + 1, b + n + 1);if(b[1].deg <= 0) break;int m = b[1].deg + 1;for(int i = 2; i < m; i ++) {ans2[cnt2 ++] = make_pair(b[1].id, b[i].id);b[i].deg --;if(b[i].deg < 0) {flag = 0; break;}}if(!ok && b[m].deg == b[m + 1].deg) {ans2[cnt2 ++] = make_pair(b[1].id, b[m + 1].id);b[m + 1].deg --;if(b[m + 1].deg < 0) {flag = 0;break;}ok = 1;}else {ans2[cnt2 ++] = make_pair(b[1].id, b[m].id);b[m].deg --;}b[1].deg = 0;}if(flag == 0) {printf("IMPOSSIBLE\n");}else if(flag == 1) {printf("UNIQUE\n");printf("%d %d\n", n, sum / 2);for(int i = 0; i < cnt1; i ++) {printf("%d", ans1[i].first);if(i != cnt1 - 1) printf(" ");}printf("\n");for(int i = 0; i < cnt1; i ++) {printf("%d", ans1[i].second);if(i != cnt1 - 1) printf(" ");}printf("\n");}else if(flag == 2) {printf("MULTIPLE\n");printf("%d %d\n", n, sum / 2);for(int i = 0; i < cnt1; i ++) {printf("%d", ans1[i].first);if(i != cnt1 - 1) printf(" ");}printf("\n");for(int i = 0; i < cnt1; i ++) {printf("%d", ans1[i].second);if(i != cnt1 - 1) printf(" ");}printf("\n");printf("%d %d\n", n, sum / 2);for(int i = 0; i < cnt2; i ++) {printf("%d", ans2[i].first);if(i != cnt2 - 1) printf(" ");}printf("\n");for(int i = 0; i < cnt2; i ++) {printf("%d", ans2[i].second);if(i != cnt2 - 1) printf(" ");}printf("\n");}}return 0;
}
Havel-Hakimi定理问题相关推荐
- Havel—Hakimi定理(度序列)
对于图的所有顶点,我们可以统计出每个顶点的度.像这样的一串数字,我们称之为:度序列.那么反过来,给定一个序列,能否判断这个序列是可图的呢?这里有一个定理:Havel-Hakimi定理可以用来判定一个序 ...
- Havel–Hakimi算法学习笔记(哈维尔算法)详细【Python】
问题 来源离散数学的图论中 第一个接触到的算法:Havel–Hakimi算法 (哈维尔算法) 判断一个非负序列是否为某无向简单图的度数列的方法(Pyhton代码) 前提提要 1.无向简单图 首先先了解 ...
- 【图论】已知度数列情况下的简单无向图的判断方法
感谢评论区大佬@goodloveyourlove补充的判断度数列是否能构成无向树的方法与例子. 关于度数列是否能构成无向树的判断方法可以移步至评论区. ======================== ...
- Codeforces 1091E New Year and the Acquaintance Estimation Erdős–Gallai定理
题目链接:E - New Year and the Acquaintance Estimation 题解参考: Havel–Hakimi algorithm 和 Erdős–Gallai theore ...
- 图的可视化问题、havel-hakimi算法、Erdős–Gallai定理
图的可视化问题.havel-hakimi算法.Erdős–Gallai定理 简单无向图的可视化问题: 给定一个度数序列D={a1......an},a⊂Z+,aiD=\{a_1......a_n\}, ...
- 连通域最小外接矩形算法原理_算法|图论 2W字知识点整理(超全面)
作者:SovietPower✨ 链接:https://ac.nowcoder.com/discuss/186584 来源:牛客网 度数序列 对于无向图, 为每个点的度数.有 (每条边被计算两次).有偶 ...
- 离散数学图论知识总结
前言 马上过段时间期末就要离散考图论了,很多知识根本记不住(因为一部分是用日语学习的),在这里稍微码一下. 第一部分 图的定义和握手定理 基本定义 给出一个名为G无向图,V(G)表示图的点集合,E(G ...
- 如何判断一个度数数列能否构成简单图
基于"Havel Hakimi"算法的判断是否构成简单图的方法 第一步 观察度数为奇数的数列是不是偶数个,例如2,3,3,1这个数列的度数为奇数的数有奇数个,不能构成简单图 如果满 ...
- Degree Sequence of Graph G
问题描述 王海洋是一个坚强乐观的中国青年.虽然出生和成长在北方内陆城市哈尔滨,但他对无边无际的海洋有着深厚的爱和向往.毕业后,他来到一个沿海城市,在一家海运公司找到了一份工作.在那里,他在一艘货轮上担 ...
- [matlab]havel定理证明(笔记)
[matlab]havel定理证明 是否可以由度序列生成简单图是图论中一个重要的内容. havel定理是解决这一问题的重要方法. havel定理证明 问题引出 简单图化问题 简单图 简单图即是指图上不 ...
最新文章
- boost::owner_less相关的测试程序
- mysql8.0.15远程登陆权限,MySQL8.0给root用户赋予远程连接权限
- Java实现AVL平衡树
- 详解 6 大主流深度学习框架
- 关于字体的一些知识,以及分享一些免费可商用字体
- Ozone SCM HA设计浅谈
- leach算法的实现过程_LEACH算法源代码
- dubbo源码解析-服务暴露原理
- 【原创】无锁编程技术及实现
- 痴情人, 浮生梦(上)
- longhorn介绍
- 联邦学习首次被纳入Gartner隐私计算技术成熟度曲线
- 开机总是进行磁盘检查
- linkerd2 php 微服务,在 Linkerd2 中进行流量拆分
- nabc模型_团队开发-极速蜗牛-NABC模型
- java 周几_java根据日期获取周几和获取某段时间内周几的日期
- AttributeError: module ‘tensorflow_core.compat.v1‘ has no attribute ‘contrib‘
- 为什么出价策略会进入学习期,周期是多久。
- 计算机行业前景6,目前10大最有发展前景的行业,人工智能第六,有你喜欢的行业吗?...
- HZNUOJ 1588 最大值最小值
热门文章
- 信捷PLC的C语言程序写法例子
- 凤凰网股票数据定向爬虫——改编自北京理工大学嵩天老师的课程实例
- Ubuntu 6.10 (Edgy) 黑体解决方案
- python实现pdf转png(转载)
- 昵图网共享分下载代包下素材nipic呢图下载币图网设计素材下载
- easyui支持ie8浏览器
- 64位win7系统中vb工程显示加载MSCOMCTL.OCX失败
- python语音识别分析_Python语音识别(计算器)
- python getsize函数_Python getsizeof()和getsize()区分详解
- QT Creator 7 如何同时运行多个客户端窗口(Client)