You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int N = 1e4 + 10 ; //题目中说结点数最大10^4=1e4
const int M = 1e5 * 2 + 10 ; //边数上限, 因为是无向图, 所以记录两次, 就是1e5*2
/*
根据题意可知二分图染色。若无法被染成二分图, 输出Impossible;
反之, 对于每个二分图, 记录两种颜色的点的个数, 取min后记录答案中。
注意, 图可能不连通。因此对于每个二分图, 都要进行取min操作, 而不是对整个图染色后取min。
*/
int color [ N ] ; //0:未上色, 1: 黑色, 2: 白色
int n , m , ans ;
//广度优先搜索的队列
queue < int > q ;
//链式前向星
struct Edge {
int to , next ;
} edge [ M ] ;
int idx , head [ N ] ;
void add ( int u , int v ) {
edge [ + + idx ] . to = v ;
edge [ idx ] . next = head [ u ] ;
head [ u ] = idx ;
}
//广度优先搜索
int bfs ( int a ) {
int ans1 = 1 , ans2 = 0 ;
color [ a ] = 1 ; //假设用颜色1着了色
q . push ( a ) ;
while ( ! q . empty ( ) ) {
int u = q . front ( ) ;
q . pop ( ) ;
for ( int i = head [ u ] ; i ; i = edge [ i ] . next ) {
int v = edge [ i ] . to ;
//目标点未着色
if ( color [ v ] = = 0 ) {
//来源点是黑的,那么目标点是白的
if ( color [ u ] = = 1 ) color [ v ] = 2 , ans2 + + ;
//来源点是白的,那么目标点是黑的
else if ( color [ u ] = = 2 ) color [ v ] = 1 , ans1 + + ;
q . push ( v ) ;
} else
//如果已着色,那么需要判断和现在的要求是不是有冲突:
if ( color [ v ] = = color [ u ] ) { //相临的存在冲突
printf ( " Impossible " ) ;
exit ( 0 ) ;
}
}
}
//哪个小就用哪个
return min ( ans1 , ans2 ) ;
}
int main ( ) {
//n个结点, m条边
cin > > n > > m ;
//m条边
for ( int i = 1 ; i < = m ; + + i ) {
int x , y ;
cin > > x > > y ;
add ( x , y ) , add ( y , x ) ; //无向图双向建边,题目中明显说是无向图!
}
//注意, 图可能不连通。因此对于每个二分图, 都要进行取min操作,
//而不是对整个图染色后取min。
//这里有一个小技巧,就是遍历每个结点,如果此结点没有上过色,就表示是一个独立的图,需要单独计算
for ( int i = 1 ; i < = n ; + + i )
if ( ! color [ i ] ) ans + = bfs ( i ) ;
//输出
printf ( " %d " , ans ) ;
return 0 ;
}