(搜索)单向公路[swustoj85]

(搜索)单向公路[swustoj85]

题目描述

某个地区有许多城镇,但并不是每个城镇都跟其他城镇有公路连接,且有公路的并不都能双向行驶。现在我们把这些城镇间的公路分布及允许的行驶方向告诉你,你需要编程解决通过公路是否可以从一个城镇到达另一个城镇。(我们规定,城镇自己跟自己可互相到达,即A可到达A).

输入

第一行只有一个数N,下面将跟着2N行数据. 在前N行数据中,对于每行数据,最开头一个数字number,表明这一行总共有number个数,number的下一个数为i,代表编号为i的那个城镇.这行余下的就是跟i有公路连接的城镇的(编号)名单,且只能从城镇i驶向其他城镇。如 4 1 2 3,表明:此行有4个数,跟城镇1有公路连接的城镇是编号为2和3的城镇.是从1连到2 和3 ,不能从2 和3 连到1. 在后N行数据中,每行由两个数字组成a,b(表示城镇的编号). 对于每个输入的数有如下关系 0 <= input_number <= 1000 .

输出

对于输入数据中的每个a,b,判断是否可以从城镇a通过公路到达城镇b,如果可以,输出Yes;否则输出No.

样例输入

3
4 1 2 3
3 4 5
3 5 8
1 2
1 8
4 8

样例输出

Yes
No
Yes

分析:

BFS,num[i]是存从i点有多少条出边,maze[i][j]存的是从i点到j点有路。

代码:

#include<bits/stdc++.h>
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
int num[1010],maze[1010][1010]={0},vis[1010];
int bfs(int be,int en)
{
	queue<int> que;
	int i;
	que.push(be);
	while(!que.empty())
	{
		int pre=que.front();
		vis[pre]=1;
		que.pop();
		if(pre==en)
			return 1;
		else
		{
			for(i=1;i<=num[pre];i++)
				if(vis[maze[pre][i]]==0)
					que.push(maze[pre][i]);
		}
	}
	return 0;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int n,i;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		int j,t,a,b;
		cin>>t>>a;
		num[a]=t-2;
		for(j=1;j<=t-2;j++)
		{
			cin>>b;
			maze[a][j]=b;
		}
	}
	for(i=1;i<=n;i++)
	{
		memset(vis,0,sizeof(vis));
		int x,y;
		cin>>x>>y;
		if(bfs(x,y))
			cout<<"Yes"<<endl;
		else
			cout<<"No"<<endl;
	}
	return 0;
}

再附上大佬宏哥DFS代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int maxn=1e6+10;
const ll mod=1e9+7;
const int INF = 0x3f3f3f3f;
inline int read () {
    register int s = 0, w = 1;
    register char ch = getchar ();
    while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
    while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
    return s * w;
}

int d[1002][1002],vis[1002],ma[1002];
int a,b,f;
void dfs(int a)
{
    int i;
    if(a==b)
    {
        f = 1;
        return;
    }
    for(i = 0; i < ma[a]; i++)
    {
        if(vis[d[a][i]] == 0)
        {
            vis[d[a][i]] = 1;
            dfs(d[a][i]);
        }
    }
 
}
int main()
{
    int t,n,k,i,j;
    t=read();
    for(i = 0; i < t; i++)
        {
            n=read();
            k=read();
            ma[k] += n - 2;
            for(j = 0; j < n - 2; j++)
            {
                d[k][j]=read();
            }
        }
    for(i = 0; i < t; i++)
    {
        a=read();
        b=read();
        memset(vis,0,sizeof(vis));
        f = 0;
        dfs(a);
        if(f)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值