题意:在一张无向图中,有n条边,判断是否存在边数量分别为奇数与偶数的环
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5215
思路:并查集判奇偶环,将每个点的编号*2,每次分别将(2*u,2*v+1)与(2*u+1,2*v)两组边合并,在合并过程中通过判断(2*u,2*v+1)判偶环,结束合并后遍历所有节点用(2*u,2*u+1)判奇环
注意点:无
以下为AC代码:
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
13627499 | 2015-05-05 11:32:20 | Accepted | 5215 | 483MS | 6876K | 1730 B | C++ | luminous11 |
/*
***********************************************
*# @Author : Luminous11 (573728051@qq.com)
*# @Date : 2015-05-04 22:55:33
*# @Link : http://blog.csdn.net/luminous11
***********************************************
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:10240000000,10240000000")
using namespace std;
#define clr(a, v) memset( a , v , sizeof(a) )
using namespace std;
const double eps = 1e-10;
const double pi = acos(-1.0);
int fa[300005];
int flag_1;
int flag_2;
void init()
{
flag_1 = flag_2 = 0;
for ( int i = 0; i < 300005; i ++ )fa[i] = i;
}
int find ( int x )
{
if ( x == fa[x] ){
return x;
}
else{
fa[x] = find ( fa[x] );
return fa[x];
}
}
void merge ( int x, int y )
{
int x1 = find ( 2 * x );
int y1 = find ( 2 * y + 1 );
if ( x1 == y1 )flag_2 = 1;
else fa[x1] = y1;
int x2 = find ( 2 * x + 1 );
int y2 = find ( 2 * y );
if ( x2 == y2 );
else fa[x2] = y2;
}
int main()
{
ios::sync_with_stdio ( false );
int T;
scanf ( "%d", &T );
while ( T -- ){
int m, n;
init();
scanf ( "%d%d", &n, &m );
int u, v;
for ( int i = 0; i < m; i ++ ){
scanf ( "%d%d", &u, &v );
merge ( u, v );
}
for ( int i = 1; i <= n; i ++ ){
if ( find ( 2 * i ) == find ( 2 * i + 1 ) ){
flag_1 = 1;
}
}
if ( flag_1 )printf ( "YES\n" );
else printf ( "NO\n" );
if ( flag_2 ) printf ( "YES\n" );
else printf ( "NO\n" );
}
return 0;
}