封锁阳光大学
https://www.luogu.com.cn/problem/P1330
- 将无向染成两种颜色,求两种颜色中出现次数少的次数
- 本题解用bfs染色,由于图可能不是连通的,所以外层循环遍历每个连通分图
- 从出发点开始bfs所有它连接到的点,如果这个点的颜色和自己一样那么就不行,否则就可以入队标记并该颜色的数量加一
- flag数组内0代表未访问,1,2分别代表标记不同的颜色
// https://www.luogu.com.cn/problem/P1330
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX 100050
queue<int> q;
int head[MAX], sum[3], flag[MAX], idx;
struct Node
{
int to, nex;
} edge[MAX * 10];
void bfs(int s)
{
q.push(s);
sum[1] = sum[2] = 0;
flag[s] = 1;
sum[flag[s]]++;
while (!q.empty())
{
int from = q.front();
q.pop();
for (int i = head[from]; i; i = edge[i].nex)
{
int to = edge[i].to;
if (flag[to] == flag[from])
{
printf("Impossible");
exit(0);
}
if (flag[to] == 0)
{
flag[to] = flag[from] % 2 + 1;
sum[flag[to]]++;
q.push(to);
}
}
}
}
void add(int u, int v)
{
edge[++idx] = (Node){v, head[u]};
head[u] = idx;
}
int n, m;
void input()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
add(b, a);
}
}
int ans;
int main()
{
input();
for (int i = 1; i <= n; i++)
if (flag[i] == 0)
{
bfs(i);
ans += min(sum[1], sum[2]);
}
cout << ans;
}