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.
|
|
|
|
#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;
|
|
|
|
|
}
|