二分图判断——sgu 172. eXam

自己的代码:
用到了STL实现:
把两个二分集合分别保存在两个set容器里
在用queue实现可以对后面有影响的组合先进入set容器
二分图判断——sgu 172. eXam View Code
    
      
#include < stdio.h >
#include
< set >
#include
< queue >
#include
< algorithm >
#include
< iostream >
using namespace std;

char hash[ 209 ][ 209 ];
bool x[ 30009 ];

struct data
{
int a,b;
};

int cmp(data x,data y)
{
return x.a < y.a;
}

int main()
{
int n,m;
scanf(
" %d%d " , & n, & m);

set < int > set1;
set < int > set2;
queue
< data > qq;
int i,j;
for (i = 1 ;i <= n;i ++ )
{
for (j = 1 ;j <= n;j ++ )
{
hash[i][j]
= 0 ;
}
}
data t;
for (i = 0 ;i < m;i ++ )
{
int a,b;
scanf(
" %d%d " , & a, & b);


t.a
= a;
t.b
= b;
qq.push(t);

}

bool cuo = 0 ;
t
= qq.front();
qq.pop();
set1.insert(t.a);
set2.insert(t.b);
if (t.a == t.b)
{
printf(
" no\n " );
return 0 ;
}
x[t.b]
= 1 ;
while ( ! qq.empty())
{
t
= qq.front();
qq.pop();
if (set1.find(t.a) != set1.end() && set1.find(t.b) != set1.end())
{
cuo
= 1 ;
break ;
}

if (set2.find(t.a) != set2.end() && set2.find(t.b) != set2.end())
{
cuo
= 1 ;
break ;
}

if (set1.find(t.a) != set1.end())
{
if (set2.find(t.b) == set2.end())
{
set2.insert(t.b);
x[t.b]
= 1 ;
}
continue ;
}

if (set2.find(t.a) != set2.end())
{
set1.insert(t.b);
continue ;
}

if (set1.find(t.b) != set1.end())
{
if (set2.find(t.a) == set2.end())
{
set2.insert(t.a);
x[t.a]
= 1 ;
}
continue ;
}

if (set2.find(t.b) != set2.end())
{
set1.insert(t.a);
continue ;
}
if (hash[t.a][t.b] < 100 ) // 一开始hash[t.a][t.b]==0会错是因为可能要先知道最后一个
{ // 然后知道最后第二个……只一次就会只考虑到最后一次……开100也只是保守数
hash[t.a][t.b] ++ ;
qq.push(t);
}
else
{
set1.insert(t.a);
set2.insert(t.b);
x[t.b]
= 1 ;
}
}

if (cuo == 0 )
{
int add = 0 ;
printf(
" yes\n " );
for (i = 1 ;i <= n;i ++ )
{
if (x[i] == 0 )
add
++ ;
}
printf(
" %d\n " ,add);
for (i = 1 ;i <= n;i ++ )
{
if (x[i] == 0 )
{
printf(
" %d " ,i);
break ;
}
}
for (i = i + 1 ;i <= n;i ++ )
{
if (x[i] == 0 )
printf(
" %d " ,i);
}
printf(
" \n " );
}
else
{
printf(
" no\n " );
}
return 0 ;
}
通用的DFS算法:
二分图判断——sgu 172. eXam View Code
    
      
#include < stdio.h >
#include
< iostream >
using namespace std;

const int maxn = 201 ;
int n, m, color[maxn];
bool g[maxn][maxn];

bool dfs( int now)
{
if (color[now] ==- 1 )color[now] = 0 ;
for ( int i = 1 ;i <= n;i ++ ){
if (i == now ||! g[i][now]) continue ;
if (color[i] !=- 1 && color[i] == color[now])
return false ;
else if (color[i] ==- 1 )
{
color[i]
= (color[now] ^ 1 );
if ( ! dfs(i)) return false ;
}
}
return true ;
}

int main()
{
scanf(
" %d %d " , & n, & m);
int x, y,i;
for (i = 1 ; i <= n; i ++ ) color[i] =- 1 ;
for (i = 1 ; i <= m; i ++ ){
scanf(
" %d %d " , & x, & y);
g[x][y]
= g[y][x] = true ;
}
for (i = 1 ; i <= n; i ++ )
{
if (color[i] ==- 1 )
if ( ! dfs(i))
{
printf(
" no\n " );
return 0 ;
}
}
printf(
" yes\n " );
int s = 0 ;
for (i = 1 ;i <= n;i ++ ) if (color[i] == 0 )s ++ ;
printf(
" %d\n " ,s);
for (i = 1 ;i <= n;i ++ ) if (color[i] == 0 ){printf( " %d " ,i); break ;}
for (i = i + 1 ;i <= n;i ++ ) if (color[i] == 0 ){printf( " %d " ,i);}
printf(
" \n " );
return 0 ;
}

你可能感兴趣的:(二分图)