UVa 10557 & HDU 1317 - XYZZY

传送门UVa 10557 & HDU 1317 - XYZZY


题意是给我们一坨房间,每个房间都有通向其他房间的通道。

一开始我们有100点的能量,求能不能到达最终房间。


因为可以回到走过的房间,这样能量就可能无限大。所以只要用DFS先找出有没有这样一个房间,如果有,那么从这个房间开始用BFS,能量就不是问题了,只要判断能不能走到。


一开始我用STL存储各个房间的数据。。TLE了好多次,我还以为是算法的问题,看了好几遍都找不出错。

后来变成存储各个房间的编号,AC。

这个教训告诉我不要什么东西都往STL里面装,也要考虑占用空间的问题,算是没白调试这几个小时了。

详情见代码


#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

struct Room
{
	int value, roomCount;
	int nextRoom[110];
	int num;
};

int n;
bool flag;
int vis[110];
int roomEnergy[110];
Room rom[110];	//存放各个房间的数据。
queue<int> qu;

void BFS(int num);
void DFS(int num, int energy);

int main()
{
	//freopen("input.txt", "r", stdin);
	int i, j;
	while (scanf("%d", &n) && n != -1)
	{
		memset(vis, 0, sizeof(vis));
		flag = false;
		for (i = 1; i <= n; i++)
		{
			scanf("%d%d", &rom[i].value, &rom[i].roomCount);
			rom[i].num = i;
			for (j = 0; j < rom[i].roomCount; j++)
				scanf("%d", &rom[i].nextRoom[j]);
		}
		DFS(1, 100);
		if (flag == false)	//说明死在半路了
			printf("hopeless\n");
	}
	return 0;
}

void DFS(int num, int energy)
{
	if (num == n)
	{
		flag = true;		//如果开启了flag,就不会再DFS了。
		printf("winnable\n");
		return;
	}
	if (vis[num] && energy <= roomEnergy[num] || flag)
		return;
	else if (vis[num] && energy > roomEnergy[num])
	{		
		BFS(num);
		return;
	}
	vis[num] = 1;
	roomEnergy[num] = energy;
	for (int i = 0; i < rom[num].roomCount; i++)
	{
		if (energy + rom[rom[num].nextRoom[i]].value > 0 && !flag)
			DFS(rom[num].nextRoom[i], energy + rom[rom[num].nextRoom[i]].value);
	}
	return;
}

void BFS(int num)
{
	memset(vis, 0, sizeof(vis));
	flag = true;
	vis[num] = 1;
	qu.push(num);
	while (!qu.empty())
	{
		int now = qu.front();
		if (now == n)
		{
			printf("winnable\n");
			while (!qu.empty())
				qu.pop();
			return;
		}
		vis[now] = 1;
		for (int i = 0; i < rom[now].roomCount; i++)
		{
			if (!vis[rom[now].nextRoom[i]])
				qu.push(rom[now].nextRoom[i]);
		}
		qu.pop();
	}
	printf("hopeless\n");
	return;
		
}




你可能感兴趣的:(ACM,HDU,uva)