NOIP2014寻找道路
题目描述 Description
在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。
2 .在满足条件1 的情况下使路径最短。
注意:图G 中可能存在重边和自环,题目保证终点没有出边。
请你输出符合条件的路径的长度。
1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。
2 .在满足条件1 的情况下使路径最短。
注意:图G 中可能存在重边和自环,题目保证终点没有出边。
请你输出符合条件的路径的长度。
输入输出格式 Input/output
输入格式:
输入文件名为road .in。
第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边。
接下来的m 行每行2 个整数x 、y ,之间用一个空格隔开,表示有一条边从点x 指向点y 。
最后一行有两个用一个空格隔开的整数s 、t ,表示起点为s ,终点为t 。
输出格式:
输出文件名为road .out 。
输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出- 1 。
输入文件名为road .in。
第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边。
接下来的m 行每行2 个整数x 、y ,之间用一个空格隔开,表示有一条边从点x 指向点y 。
最后一行有两个用一个空格隔开的整数s 、t ,表示起点为s ,终点为t 。
输出格式:
输出文件名为road .out 。
输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出- 1 。
对于30%的数据,0<n≤10,0<m≤20;
对于60%的数据,0<n≤100,0<m≤2000;
对于100%的数据,0<n≤10,000,0<m≤200,000,0<x,y,s,t≤n,x≠t。
对于100%的数据,0<n≤10,000,0<m≤200,000,0<x,y,s,t≤n,x≠t。
题解
在反图上bfs,再在正图上bfs。。。我都不想说了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #define ll long long using namespace std; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,cnt; int S,T; int q[10005],dis[10005]; int u[200005],v[200005]; bool vis[10005]; struct data{int to,next;}e[400005];int last[10005]; void insert(int u,int v) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; } void bfs1() { int head=0,tail=1; q[0]=T;vis[T]=1; while(head!=tail) { int now=q[head];head++; for(int i=last[now];i;i=e[i].next) { if(!vis[e[i].to]) { vis[e[i].to]=1; q[tail++]=e[i].to; } } } } bool che(int now) { for(int i=last[now];i;i=e[i].next) if(!vis[e[i].to])return 0; return 1; } bool bfs2() { int head=0,tail=1; q[0]=S;dis[S]=0; while(head!=tail) { int now=q[head];head++; if(!che(now))continue; for(int i=last[now];i;i=e[i].next) if(dis[e[i].to]==-1) { dis[e[i].to]=dis[now]+1; q[tail++]=e[i].to; if(e[i].to==T) { printf("%d\n",dis[T]); return 1; } } } return 0; } int main() { n=read();m=read(); for(int i=1;i<=m;i++) { u[i]=read(),v[i]=read(); if(u[i]!=v[i]) insert(v[i],u[i]); } S=read();T=read(); bfs1(); cnt=0;memset(last,0,sizeof(last)); memset(dis,-1,sizeof(dis)); for(int i=1;i<=m;i++) if(u[i]!=v[i]) insert(u[i],v[i]); if(!vis[S]){puts("-1");return 0;} if(!bfs2())puts("-1"); return 0; } |
朋友们,你们可不要随便模仿神犇KuriboG用dfs求最短路哦
哈哈哈
。。。这样真的好么。。。不过好歹还有30分