洛谷P1330 - 封锁阳光大学 - DFS
封锁阳光大学 - DFS
https://www.luogu.org/problemnew/show/P1330
代码&题解参照 https://www.luogu.org/blog/Kesdiael3/solution-p1330
这是一题特殊的搜索题,搜索和染色结合。
注意事项如下:
一、数据可能给的不连通:要重新遍历每一个点,并且需要一个used数组表示有没有搜索过这个点。
二、这一个DFS其实不需要回溯,因为染色的情况是唯一确定的,这样可以快很多。
三、对于不连通的每一部分图,应该分别计算并且相加结果。
四、还要注意题目中是求最小的,所以应该判断两种颜色较小的那一种。
#include <iostream>
using namespace std;
class Edge
{
public:
int v;
int next;
Edge(): v(0), next(0) {}
};
Edge edge[1000001];
int head[100001];
int cnt;
void add(int u, int v)
{
cnt++;
edge[cnt].next = head[u];
edge[cnt].v = v;
head[u] = cnt;
}
int n;
int m;
int used[100001];
int col[100001];
int sum[2];
bool DFS(int node, int color)
{
if (used[node]) //搜过了吗
if (col[node] == color) //颜色一样吗
return true;
else
return false;
used[node] = 1;
sum[color]++;
col[node] = color;
for (int i=head[node]; i; i=edge[i].next)
if (!DFS(edge[i].v, 1 - color))
return false;
return true;
}
int main()
{
int x, y;
cin >> n >> m;
for (int i=1; i<=m; i++)
{
cin >> x >> y;
add(x, y);
add(y, x);
}
int ans = 0;
for (int i=1; i<=n; i++) //遍历每一个节点:防止图不连通
{
if (used[i])
continue; //这一点所属于的部分已经计算过
sum[0] = 0;
sum[1] = 0;
if (!DFS(i, 0)) //染色失败
{
cout << "Impossible";
return 0;
}
ans += min(sum[0], sum[1]);
}
cout << ans << endl;
return 0;
}
要段考了……有点慌……这几天必须加紧复习了……

浙公网安备 33010602011771号