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 ...
随机推荐
- 修改TFS与本地源代码映射路径
使用源代码管理资源管理器修改工作区 在“文件”菜单上单击“源代码管理”,再单击“工作区”. 在“管理工作区”对话框的“名称”列下,突出显示要修改的工作区,然后单击“编辑”. 在“编辑工作区”对话框中: ...
- input时间输入框小解
date 年月日 month 年月 week 年周(ios上不可用,android部分会显示当前是第几周) time 时分(ios不显示时/分的字样) datetime 为一输入框,基本 ...
- webservice简介及客户端搭建
在环境变量中,CLASSPATH添加D:\apache-cxf-2.4.2\lib 新建CXF_HOME D:\apache-cxf-2.4.2 在PATH中添加 D:\apache-cxf- ...
- IOS应用的国际化
IOS应用的国际化,主要分为3个部分: Info.plist 文件的国际化 .xib文件的国际化 .m文件的国际化 下面我就来一一说明. Info.plist 文件的国际化我们使用Xcode 4.5 ...
- Qt - 设置TableWidget只读
ui->infoViewTW->setEditTriggers(QAbstractItemView::NoEditTriggers); enum QAbstractItemView::Ed ...
- Java中精确的数字计算类BigDecimal
在日常开放当中需要我们计算数字,利率.通常Java的做法是使用Math相关的API.但是,这样做是不够精确的,由于float和double不能进行计算,如果强行进行计算会使得计算不准确.造成难以挽回的 ...
- 《C++ Primer》之面向对象编程(四)
纯虚函数 在前面所提到过的 Disc_item 类提出了一个有趣的问题:该类从 Item_base 继承了 net_price 函数但没有重定义该函数.因为对 Disc_item 类而言没有可以给予该 ...
- MFC中获取系统当前时间
1.使用CTime类 CString str; //获取系统时间 CTime tm; tm=CTime::GetCurrentTime(); str=tm.Format("现在时间是%Y年% ...
- JDK1.5与1.6在Override上的区别
@Override是JDK5 就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override 而JDK6 修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现都可以加上@Ove ...
- SharePoint 2010 Modal Dialog
SharePoint 2010 Modal Dialog Tweet Modal dialog play very important role to improve the user exper ...