【NOIP2014 Day2 T2】寻找道路

来源:互联网 发布:福禄克网络 dsx 8000 编辑:程序博客网 时间:2024/06/05 11:43

【NOIP2014 Day2 T2】寻找道路

Time Limit:10000MS  Memory Limit:131072K
Total Submit:33 Accepted:25 
Case Time Limit:1000MS

Description

 

Input

 

Output

 

Sample Input

样例输入1:3 21 22 11 3样例输入2:6 61 21 32 62 54 53 41 5

Sample Output

样例输出1:-1样例输出2:3

Hint

 
 
 

Source

感谢nodgd放上题目



最短路的反向边思路

用了栈优化bellman-ford,T了,用SPFA就A了,然后Dijkstra+heap是过不了(没试过,((V+E)logV)理论是过不了的),用了bellman-ford+stack(传说中比SPFA还不稳定),只是有时有奇效。

#include<cstdio>#include<queue>using namespace std;#define maxn 10009#define maxm 200009#define inf 2100000000queue <int>stk;//一开始用的stack,T了,改成queue时就懒得改变量名了。int n, m;int vt=0;int end[maxm], len[maxm], next[maxm], last[maxn], start[maxm];int dis[maxn];bool is_in[maxn], can_arr[maxn];void adde(int s, int e, int l){vt++;start[vt]=s;end[vt]=e;len[vt]=l;next[vt]=last[s];last[s]=vt;}void bellman_ford(int s){int i, cur; for(i=1; i<=n; i++)dis[i]=inf;dis[s]=0;stk.push(s);is_in[s]=true;while(!stk.empty()){cur=stk.front();stk.pop();is_in[cur]=false;for(i=last[cur]; i; i=next[i]){if(dis[end[i]]>dis[cur]+len[i]){dis[end[i]]=dis[cur]+len[i];if(!is_in[end[i]]){stk.push(end[i]);is_in[end[i]]=true;}}}}}inline void _read(int& d){char t=getchar();bool f=false;while(t<'0'||t>'9') {if(t=='-') f=true; t=getchar();}for(d=0;t<='9'&&t>='0';t=getchar()) d=d*10+t-'0';if(f) d=-d;}inline void _out(int d){int o[30],top=1;if(d==0){putchar('0');return ;}if(d<0) {putchar('-');d=-d;}while(d){o[top++]=d%10;d/=10;}for(--top;top;--top) putchar('0'+o[top]);}int main(){int i, j;int ts, te, s, e;scanf("%d%d", &n, &m);for(i=1; i<=m; i++){_read(ts), _read(te);if(ts!=te){adde(te, ts, 1);}}scanf("%d%d", &s, &e);for(i=1; i<=n; i++)can_arr[i]=true;bellman_ford(e);for(i=1; i<=vt; i++){if(dis[start[i]]==inf){len[i]=inf;can_arr[end[i]]=false;}}for(i=1; i<=vt; i++){if(can_arr[end[i]]==false){len[i]=inf;}}bellman_ford(e);printf("%d", dis[s]==inf?(-1):dis[s]);return 0;}


1 1