HDU 5215 BestCoder"杯中国大学生程序设计冠军赛” 边双连通分量取出子图+二分染色判图内奇偶环
Cycle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 865 Accepted Submission(s): 241
Question 1: Can X be a odd number ?
Question 2: Can X be a even number ?
(note: you must walk, so X can't be 0)
Each test case begins with two integer N, M, indicating the number of vertexes and the number of edges. Following M lines, each line contains two integers Ui, Vi, indicating there are a edge between vertex Ui and vertex Vi.
T is about 30
1 ≤ N ≤ 100000
0 ≤ M ≤ 300000
1 ≤ Ui,Vi ≤ N
Ui will not equal to Vi
There is at most one edge between any pair of vertex.
The first line contains "YES" or "NO" for question 1.
The second line contains "YES" or "NO" for question 2.
1 0
3 3
1 2
2 3
3 1
4 4
1 2
2 3
3 4
4 1
NO
YES
NO
NO
YES
If you need a larger stack size,
please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.
题目大意:给你一个有n个顶点的无向图和m条边,从任意一点出发(经过的边不能再经过),问能否通过走偶数步或者奇数步再回到原点。
思路:首先我们用边双连通分量把所有的符合条件的极大子图都给取出来,然后我们分别对极大子图进行求解。边双连通分量有个特性,不存在和其他的子图有公共点或者公共边。所以我们每次都只要考虑当前子图内部即可。接下来进行分类讨论:
①如果只有一个偶环,或者全都是偶环,那么就是偶数步。 ②如果只有一个奇环,那么就只能走奇数步。③如果子图内有多个奇环或子图内奇偶环都有,那么偶数and奇数都可以。
因此,奇偶环的判定我们就用二分图染色,即可以得到偶环和奇环,并且我们得到奇环以后让cnt++即可,并且不进行return即可。
//看看会不会爆int! 或者绝对值问题。
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define all(a) a.begin(), a.end()
const int maxn = + ;
vector<int> G[maxn], bcc[maxn];
int bccno[maxn], pre[maxn], low[maxn];
int n, m, dfstime, bcc_cnt;
stack<int> s; void dfs(int u, int fa){
low[u] = pre[u] = ++dfstime;
int len = G[u].size();
s.push(u);
for (int i = ; i < len; i++){
int v = G[u][i];
if (pre[v] == -){
dfs(v, u);
low[u] = min(low[u], low[v]);
}
else if(bccno[v] == ){
low[u] = min(low[u], pre[v]);
}
}
if (low[u] == pre[u]){
bcc_cnt++;
while (true){
int x = s.top(); s.pop();
bccno[x] = bcc_cnt;
bcc[bcc_cnt].pb(x);
if (x == u) break;
}
}
return ;
}
int color[maxn], vis[maxn], myodd, myeven;
bool flag;
void draw(int u, int fa){
int len = G[u].size();
for (int i = ; i < len; i++){
int v = G[u][i];
if (bccno[v] != bccno[u]) continue;
if (color[v] != -){
if (v == fa) continue;
if (color[u] == color[v]) {
myodd++;
}
else myeven = ;
}
else {
color[v] = - color[u];
draw(v, u);
}
}
return ;
} int main(){
int t; cin >> t;
while (t--){
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) G[i].clear(), bcc[i].clear();
for (int i = ; i <= m; i++){
int u, v; scanf("%d%d", &u, &v);
G[u].pb(v), G[v].pb(u);
}
memset(bccno, , sizeof(bccno));
memset(pre, -, sizeof(pre));
memset(low, -, sizeof(low));
dfstime = bcc_cnt = ;
for (int i = ; i <= n; i++){
if (pre[i] == -){
dfs(i, -);
}
}
memset(color, -, sizeof(color));
///如果能染色,表示是偶环,反之存在奇环
int odd = , even = ;
for (int i = ; i <= bcc_cnt; i++){
if (bcc[i].size() > ){
myodd = myeven = ;
color[bcc[i][]] = ;
draw(bcc[i][], -);
myodd /= ;
if (myeven == ) even = ;
if (myodd == ) odd = ;
if (myodd > ) even = odd = ;
}
if (odd == && even == ) break;
}
printf("%s\n", odd ? "YES" : "NO");
printf("%s\n", even ? "YES" : "NO");
}
return ;
} /*
100
7 8
1 2
2 3
1 3
2 4
4 5
5 6
6 7
7 4 ans:
yes yes
yes yes
*/
学习点:对边连通分量的实际意义的使用
HDU 5215 BestCoder"杯中国大学生程序设计冠军赛” 边双连通分量取出子图+二分染色判图内奇偶环的更多相关文章
- ACM 五一杭电赛码"BestCoder"杯中国大学生程序设计冠军赛小记
对于这项曾经热爱的竞赛,不得不说这是我最后一年参加ACM比赛了,所以要珍惜每一次比赛的机会. 五一去杭电参加了赛码"BestCoder"杯中国大学生程序设计冠军赛,去的队伍包括了今 ...
- 个人训练记录-赛码"bestcoder"杯中国大学生程序设计冠军赛
A.Movie 题意是给n个线段,要求求出是否存在三个不相交的线段,是的话输出yes,否则输出no.根据贪心的想法,可以先找出右端点r'最小的线段,他是三条线段中最左的那条,再找出左端点l'最大的线段 ...
- HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)
http://acm.hdu.edu.cn/showproblem.php?pid=2242 题意: 思路:首先求一下双连通分量,如果只有一个双连通分量,那么无论断哪根管子,图还是连通的. 最后只需要 ...
- HDU - 6440 Dream 2018中国大学生程序设计竞赛 - 网络选拔赛
给定的\(p\)是素数,要求给定一个加法运算表和乘法运算表,使\((m+n)^p = m^p +n^p(0 \leq m,n < p)\). 因为给定的p是素数,根据费马小定理得 \((m+n) ...
- HDU 6235.Permutation (2017中国大学生程序设计竞赛-哈尔滨站-重现赛)
Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tot ...
- HDU 5963 朋友 【博弈论】 (2016年中国大学生程序设计竞赛(合肥))
朋友 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Descr ...
- HDU 5969 最大的位或 【贪心】 (2016年中国大学生程序设计竞赛(合肥))
最大的位或 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem De ...
- HDU 5968 异或密码 【模拟】 2016年中国大学生程序设计竞赛(合肥)
异或密码 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Des ...
- HDU 5961 传递 【图论+拓扑】 (2016年中国大学生程序设计竞赛(合肥))
传递 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem ...
随机推荐
- 数组实现UITabview的cell设置
- python基础(三)列表、数组、字典
列表与元组 列表是最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 1 >>> names = ['wangeq','zlx','jack','rose ...
- iOS下uiview和uiscrollview设置背景图片的源码
1.uiscrollview 设置背景图片 // Setup the Scroll ViewUIScrollView*tempScrollView=(UIScrollView*)self.view;t ...
- C语言_error_MSB8031
关于Visual Studio 2013 编译 multi-byte character set MFC程序出现 MSB8031 错误的解决办法 Visual Studio 2013 编译旧的 mul ...
- MFC通过ODBC连接Mysql程序
分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 MFC通过ODBC连接 ...
- Chapter 2 Open Book——18
"Wow," Mike said. "It's snowing."I looked at the little cotton fluffs that were ...
- 第三十一节,time时间模块
模块简介 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...
- DOM操作-动态创建网页元素
动态创建新的DOM元素,是JavaScript操作网页对象模型的重要手段之一 代码: <!DOCTYPE html> <html> <head> <title ...
- JavaScript在智能手机上的应用-测试是否支持滑动事件
---------------------------- <script type="text/javascript"> ...
- js 数组切换图片
<html> <head> <meta charset="utf-8" /> <title></title> <s ...