HDU 5215 Cycle (搜索)

这个题目跟同比赛的 Exploration类似,做法也类似。
在那道题目只需要判断出是否存在环。
而这道题目则判读这个环的边是奇数边还是偶数边。
我这边采用的方法是用num表示这个点在搜索到第几条边是被搜到。下次在被搜到的时候,边数减掉上一次搜到时候的边数,就是从这个点出发回到这个点的边数了。然后判断一下奇偶就可以了。假如已经有奇数和偶数,就不用在继续搜了,直接结束,也算是小小的剪枝。
#pragma comment(linker, "/STACK:102400000,102400000")
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
using namespace std;
#define MAX 110000
bool tg[2];
int head[MAX];
bool vis[MAX << 1];
int num[MAX];
int cnt;
struct edge
{
	int v;
	int next;
}edg[MAX << 1];

void init()
{
	cnt = 0;
	memset(head, -1, sizeof head);
	memset(num, -1, sizeof num);
	memset(vis, 0, sizeof vis);
	memset(tg, 0, sizeof tg);
}

void addedge(int u, int v)
{
	edg[cnt].v = v;
	edg[cnt].next = head[u];
	head[u] = cnt++;
	swap(u, v);
	edg[cnt].v = v;
	edg[cnt].next = head[u];
	head[u] = cnt++;
}
void dfs(int u,int cnt2)
{
	if (tg[0] && tg[1])
		return;
	for (int i = head[u]; i != -1; i = edg[i].next)
	{
		int v = edg[i].v;
		if (!vis[i])
		{
			vis[i] = 1;
			vis[i ^ 1] = 1;
			if (num[v]!=-1)
				tg[(cnt2 + 1 - num[v]) & 1] = 1;
			else
				num[v] = cnt2 + 1;
			dfs(v, cnt2 + 1);
		}
	}
}
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n, m;
		scanf("%d%d", &n, &m);
		int u, v;
		init();
		while (m--)
		{
			scanf("%d%d", &u, &v);
			addedge(u, v);
		}
		for (int i = 1; i <= n; i++)
		{
			if (num[i]==-1)
			{
				num[i] = 0;
				dfs(i, 0);
			}
		}
		if (tg[1])
			puts("YES");
		else
			puts("NO");
		if (tg[0])
			puts("YES");
		else
			puts("NO");
	}
}



你可能感兴趣的:(方法学习,搜索)