题意:
解法:
用变量x[ i] 表示点i在那个集合, x[ i] 的取值为0 / 1 ,
设j是i的出点, 为了使度数为奇数, 那么需要满足:
1. 如果i的出度是偶数, 那么:
x[ j1] ^ x[ j2] . . ^ x[ jk] = 1.
2. 如果i的出度是奇数, 那么:
x[ j1] ^ x[ j2] . . ^ x[ jk] = x[ i] ,
即x[ i] ^ x[ j1] ^ x[ j2] . . ^ x[ jk] = 0.
可以列出n个异或方程组, 高斯消元判断是否有解即可.
code:
#include <bits/stdc++.h>
using namespace std;
const int maxm= 1e3 + 5 ;
const int N= 1e3 + 5 ;
vector< int > g[ maxm] ;
int n, m;
int a[ N] [ N] , x[ N] ;
int freedom[ N] , num;
int Gauss ( int m, int n) {
int col= 0 , k= 0 ;
for ( ; k< m&& col< n; k++ , col++ ) {
int r= k;
for ( int i= k+ 1 ; i< m; i++ ) {
if ( abs ( a[ i] [ col] ) > a[ r] [ col] ) r= i;
}
if ( a[ r] [ col] == 0 ) {
freedom[ num++ ] = col;
k-- ; continue ;
}
if ( r!= k) for ( int i= col; i<= n; i++ ) {
swap ( a[ k] [ i] , a[ r] [ i] ) ;
}
for ( int i= k+ 1 ; i< m; i++ ) {
if ( abs ( a[ i] [ col] ) != 0 ) {
for ( int j= col; j<= n; j++ ) {
a[ i] [ j] ^ = a[ k] [ j] ;
}
}
}
}
for ( int i= k; i< m; i++ ) {
if ( a[ i] [ col] != 0 ) return - 1 ;
}
if ( k< n) return n- k;
for ( int i= n- 1 ; i>= 0 ; i-- ) {
x[ i] = a[ i] [ n] ;
for ( int j= i+ 1 ; j< n; j++ ) {
x[ i] ^ = ( a[ i] [ j] && x[ j] ) ;
}
}
return 0 ;
}
signed main ( ) {
cin>> n>> m;
for ( int i= 1 ; i<= m; i++ ) {
int a, b; cin>> a>> b;
a-- , b-- ;
g[ a] . push_back ( b) ;
g[ b] . push_back ( a) ;
}
for ( int i= 0 ; i< n; i++ ) {
for ( int j: g[ i] ) {
a[ i] [ j] = 1 ;
}
if ( g[ i] . size ( ) % 2 == 0 ) {
a[ i] [ n] = 1 ;
} else {
a[ i] [ i] = 1 ;
}
}
int ans= Gauss ( n, n) ;
if ( ans!= - 1 ) cout<< "Y" << endl;
else cout<< "N" << endl;
return 0 ;
}