Havel-Hakimi定理问题
来源:互联网 发布:关于大数据的书 编辑:程序博客网 时间:2024/05/16 15:09
昨天模拟了一下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 0x7fffffffusing 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定理
- poj1659 Havel-hakimi定理
- Havel-Hakimi定理
- Havel - Hakimi 定理
- Havel-Hakimi定理
- Havel-Hakimi定理
- Havel-Hakimi定理
- Havel-Hakimi定理
- Havel-Hakimi定理
- Havel-Hakimi定理 hdu2454 / poj1695 Havel-Hakimi定理
- 度序列(Havel-Hakimi定理)
- Havel-Hakimi定理及其应用
- POJ 1659(Havel-Hakimi定理)
- poj1659(Havel-Hakimi定理)
- poj 1659 havel-hakimi 定理
- POJ 1659 Havel-Hakimi定理
- Ubuntu下 解决adb server is out of date. killing... ADB server didn't ACK
- IOS info.plist配置文件
- Satellizer: 一个简单易用的、端到端的基于 token 的 AngularJS 认证模块
- 全景:一些全景网址
- PHP 判断是否包含某字符串
- Havel-Hakimi定理问题
- Android APP去除启动页出现的黑色闪现
- Java内存溢出和内存泄露
- windows平台打补丁,报错OPatch failed with error code = 74
- Salesforce Site
- 解析UML类图符号意义
- Eclipse 常用技巧功能
- jvm工具系列之--jps
- OSG 设置背景,前景