hdu 3097 The Partition of A Graph uva 11396 Claw Decomposition
2013-11-20 21:06
183 查看
这两道题比较像,就放在一起写吧。
题意:第一道题,在1000个点的无向图中,现在要把所有的边分成一对一对的,要求这一对边必须要在图中相邻,询问存不存在这样的一种划分方法。
第二道题,在400个点的图中,保证每个点的度都是3,那么现在要分成爪子的形状,就是中间一个点度为3,其他外面连接了三个点,询问能不能将图中划分成一些爪子。
想法:第一题中,如果这样考虑这个问题,将原图中的点看成边看成点,然后如果两个点是相连的,我们就加一条边,现在的问题就是看在这个1000个点中一般图最大匹配是完美匹配,但是这个时间复杂度是肯定解不出来的,那么这道题目里面有什么可以利用的性质呢,可以发现这个图是有一些特点的,因为原图中的一个点上的边是任意可以选的,所以这一部分就是完全图,整个图就是由一块块的完全图和一些公共点连接在一起组成的,把完全图部分抽象成点就可以看成一棵树,那么由因为这部分是完全图,任意两个可以匹配,所以直接看这个联通块的个数是偶数的话就可以了。
第二道题,每个点的度是3,而一个爪子中间的的度就是3,所以说这个点要么是重点,要么就是轻点,而原图中如果有两个点是相邻的,必然一个重点一个轻点,为什么(很好推),所以这不就是一个二分图模型嘛,相邻点全部在对面,假如能够形成二分图,那么两边的点数肯定是相同的,然后就是一边的全部重点,对面全部是轻点,就是爪的分解。
一下子还真没想到。。
题意:第一道题,在1000个点的无向图中,现在要把所有的边分成一对一对的,要求这一对边必须要在图中相邻,询问存不存在这样的一种划分方法。
第二道题,在400个点的图中,保证每个点的度都是3,那么现在要分成爪子的形状,就是中间一个点度为3,其他外面连接了三个点,询问能不能将图中划分成一些爪子。
想法:第一题中,如果这样考虑这个问题,将原图中的点看成边看成点,然后如果两个点是相连的,我们就加一条边,现在的问题就是看在这个1000个点中一般图最大匹配是完美匹配,但是这个时间复杂度是肯定解不出来的,那么这道题目里面有什么可以利用的性质呢,可以发现这个图是有一些特点的,因为原图中的一个点上的边是任意可以选的,所以这一部分就是完全图,整个图就是由一块块的完全图和一些公共点连接在一起组成的,把完全图部分抽象成点就可以看成一棵树,那么由因为这部分是完全图,任意两个可以匹配,所以直接看这个联通块的个数是偶数的话就可以了。
第二道题,每个点的度是3,而一个爪子中间的的度就是3,所以说这个点要么是重点,要么就是轻点,而原图中如果有两个点是相邻的,必然一个重点一个轻点,为什么(很好推),所以这不就是一个二分图模型嘛,相邻点全部在对面,假如能够形成二分图,那么两边的点数肯定是相同的,然后就是一边的全部重点,对面全部是轻点,就是爪的分解。
一下子还真没想到。。
#include <stdio.h> #include <iostream> #include <algorithm> #include <vector> #include <memory.h> #include <string> using namespace std; int n ; #define maxn 410 vector<int> G[maxn]; void read() { int m = 3 * n; int u, v; for(int i = 1;i <= n;i++) G[i].clear(); while(scanf("%d%d",&u,&v), u + v) { G[u].push_back(v); G[v].push_back(u); } } int color[maxn]; bool dfs(int u,int c) { color[u] = c; int size = G[u].size(); for(int i = 0 ;i < size;i++) { int v = G[u][i]; if(color[v] == 1 - c) continue; if(-1 == color[v]) if(false == dfs(v, 1 - c)) return false; if(color[v] == c) return false; } return true; } string solve() { memset(color, -1, sizeof(color)); for(int i = 1;i <= n;i++) if(-1 == color[i]) if(false == dfs(i, 0)) return "NO"; return "YES"; } int main() { freopen("D:\\in.txt","r",stdin); while(cin >> n ,n) { read(); cout << solve() << endl; } return 0; }
相关文章推荐
- leetcode之 Palindrome Partitioning I&II
- hdu2602Bone Collector (简箪01背包)
- C# 操作符重载
- 对于数据库设计者而言,在设计表属性类型时应该考虑哪些问题?
- win7电脑磁盘文件以分组方式展现解决方案
- android 分享功能,实现分享的程序与进行分享信息的代码
- 职责链模式----主界面显示
- 串的反转
- win7电脑磁盘文件以分组方式展现解决方案
- Linux——sed工具
- c++中struct与class的不同
- 计算机视觉的专家和网站
- foxmail 定时发邮件
- 经典C#书籍
- Codeforces 365C - Matrix(hash + yy)
- 测试——设计思维之获取反馈
- C++学习之路(一)
- qt从x86架构移植到arm架构
- s5pv210启动流程简析
- 猜数字游戏