UOJ #556. 神奇的道路
题目背景
在某教练的强迫之下,我一个蒟蒻居然又出题了!!!出题了!!!(数据太水别找我qwq)
好的,JL说好的一题100快拿来
题目描述
我们有一个有向图,每条边权值为1,我们要在上面找一条神奇的道路满足:
1.神奇的道路上的所有点的出边所指向的点都直接或间接与终点连通。
2.在满足条件1的情况下使路径最短。
3.该路径是从起点到终点的路径
垃圾出题人表示找不到这条路径,所以希望你帮忙qwq
输入格式
第一行有两个用一个空格隔开的整数 n 和 m,表示图有 n个点和 m 条边。
接下来的 m 行每行 2 个整数 x,y,之间用一个空格隔开,表示有一条边从点 x 指向点y。
最后一行有两个用一个空格隔开的整数 s, t,表示起点为 s,终点为 t。
输出格式
输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出“orz”(不含双引号)
输入输出样例
输入#1
3 2
1 2
2 1
1 3
输出#1
orz
输入#2
7 8
5 2
3 1
5 3
1 6
3 6
6 7
2 7
2 4
5 7
输出#2
3
说明/提示
对于样例一: 起点1与终点3不连通,所以满足题目描述的路径不存在,故输出orz。
数据范围
30%保证是连通图
100% 0<n≤10000,0<m≤200000,0<x,y,s,t≤n,x,s≠t。
思路
最短路+DFS
代码:
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
const int oo=0x3f3f3f3f;
int n,m,x,y,s,t;
int tot,head[N];
int cnt[N],dis[N];
int vis[N],kdl[N];
struct no {
int to,nxt,dis;
} map[N];
struct nod {
int pos,num;
};
queue<int> q;
queue<int> p;
void add(int u,int v,int w) {
tot++;
map[tot].to=v;
map[tot].nxt=head[u];
map[tot].dis=w;
head[u]=tot;
}
void spfa(int s) {
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
q.push(s);
while(q.size()) {
int tmp=q.front();
q.pop();
for(int i=head[tmp]; i; i=map[i].nxt) {
int v=map[i].to;
if(vis[v])
continue;
if(dis[v]>dis[tmp]+map[i].dis) {
dis[v]=dis[tmp]+map[i].dis;
q.push(v);
}
}
}
}
void dfs(int s) {
p.push(s);
while(p.size()) {
int tmp=p.front();
p.pop();
for(int i=head[tmp]; i; i=map[i].nxt) {
int v=map[i].to;
cnt[v]--;
if(!kdl[v]) {
p.push(v);
kdl[v]=1;
}
}
}
}
int main () {
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++) {
scanf("%d%d",&x,&y);
add(y,x,1);
cnt[x]++;
}
scanf("%d%d",&s,&t);
dfs(t);
for(int i=1; i<=n; i++)
if(cnt[i])
vis[i]=1;
spfa(t);
if(dis[s]>=oo)
printf("orz\n");
else
printf("%d\n",dis[s]);
return 0;
}

浙公网安备 33010602011771号