Codeforces Round #467 (Div. 1): B. Sleepy Game(BFS+有向图判环)



题意(经过转换):给你一个n个点m条边的有向图,再给你一个起点x,问存不存在一条路径满足①路径中有奇数条边;②终点的出度为0,如果存在输出Win,并在第二行输出这个路径(可能不唯一输出任意一种),否则你再看能不能通过这个点走进一个环中,如果可以输出Draw,环也走不进输出Lose


其实转成这个题意之后难度就降低了,因为一部分还是翻译+理解问题

判断是否为win:其实只用一个广搜就可以解决,vis[x][0/1]表示是否能在经过偶数/奇数条边的情况下到达点x,最后就是看有没有点x满足①出度为0;②vis[x][1]=1,如果有就是Win,输出路径的话直接用vis[][]记上一个点就行了

之后就是判断是否为Draw,也就是是否有环,这个就是有向图判环问题嘛,广搜求拓扑序或者深搜都可以

如果按以下方法写应该没有挂点


#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef struct
{
	int x;
	int t;
}Res;
Res now, temp;
vector<int> G[100005];
int ok, vis[100005][2], out[100005], flag[100005];
queue<Res> q;
void Print(int x, int y)
{
	if(vis[x][y]!=-1)
		Print(vis[x][y], y^1);
	printf("%d ", x);
}
void Sech(int x)
{
	int i, v;
	flag[x] = 1;
	for(i=0;i<G[x].size();i++)
	{
		v = G[x][i];
		if(flag[v]==1)
			ok = 1;
		else if(flag[v]==0)
			Sech(v);
	}
	flag[x] = 2;
}
int main(void)
{
	int n, m, i, k, x;
	scanf("%d%d", &n, &m);
	for(i=1;i<=n;i++)
	{
		scanf("%d", &x);
		out[i] = x;
		while(x--)
		{
			scanf("%d", &k);
			G[i].push_back(k);
		}
	}
	scanf("%d", &k);
	vis[k][0] = -1;
	now.x = k, now.t = 0;
	q.push(now);
	while(q.empty()==0)
	{
		now = q.front();
		q.pop();
		for(i=0;i<G[now.x].size();i++)
		{
			temp.x = G[now.x][i];
			temp.t = now.t^1;
			if(vis[temp.x][temp.t]==0)
			{
				vis[temp.x][temp.t] = now.x;
				q.push(temp);
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		if(out[i]==0)
		{
			if(vis[i][1])
			{
				printf("Win\n");
				Print(i, 1);
				puts("");
				return 0;
			}
		}
	}
	Sech(k);
	if(ok)
		printf("Draw\n");
	else
		printf("Lose\n");
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值