(搜索)单向公路[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;
}