洛谷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;
}
要段考了……有点慌……这几天必须加紧复习了……
posted @ 2018-04-18 11:35  TonyLiang2018  阅读(127)  评论(0)    收藏  举报