HDU 5215 Cycle (搜索)

這個題目跟同比賽的Exploration類似,做法也類似。
在那道題目只需要判斷出是否存在環。
而這道題目則判讀這個環的邊是奇數邊還是偶數邊。
我這邊採用的方法是用num表示這個點在搜索到第幾條邊是被搜到。下次在被搜到的時候,邊數減掉上一次搜到時候的邊數,就是從這個點出發回到這個點的邊數了。然後判斷一下奇偶就可以了。假如已經有奇數和偶數,就不用在繼續搜了,直接結束,也算是小小的剪枝。
#pragma comment(linker, "/STACK:102400000,102400000")
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
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");
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章