CODEVS——T 1269 匈牙利游戏 2012年CCC加拿大高中生信息学奥赛

http://codevs.cn/problem/1269/

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述 Description

Welcome to the Hungary Games! The streets of Budapest form a twisted network of one-way streets.

欢迎来到匈牙利游戏!布达佩斯(匈牙利首都)的街道形成了一个弯曲的单向网络。

You have been forced to join a race as part of a “Reality TV” show where you race through these streets, starting at the Sz´echenyi thermal bath (s for short) and ending at the Tomb of G¨ ul Baba (t for short).

你被强制要求参加一个赛跑作为一个TV秀的一部分节目,比赛中你需要穿越这些街道,从s开始,到t结束。

Naturally, you want to complete the race as quickly as possible, because you will get more promo- tional contracts the better you perform.

很自然的,你想要尽快的完成比赛,因为你的比赛完成的越好,你就能得到更多的商业促销合同。

However, there is a catch: any person who is smart enough to take a shortest s-t route will be thrown into the P´alv¨olgyi cave system and kept as a national treasure. You would like to avoid this fate, but still be as fast as possible. Write a program that computes a strictly-second-shortest s-t route.

但是,有一个需要了解的是,如果有人过于聪明找到从s到t的最短路线,那么他就被扔到国家极品人类保护系统中作为一个国家宝藏收藏起来。你显然要避免这种事情的发生,但是也想越快越好。写一个程序来计算一个从s到t的严格次短路线吧。

Sometimes the strictly-second-shortest route visits some nodes more than once; see Sample Input 2 for an example.

有的时候,严格次短路线可能访问某些节点不止一次。样例2是一个例子。

输入描述 Input Description

The first line will have the format N M, where N is the number of nodes in Budapest and M is the number of edges. The nodes are 1,2,...,N; node 1 represents s; node N represents t. Then there are M lines of the form A B L, indicating a one-way street from A to B of length L. You can assume that A != B on these lines, and that the ordered pairs (A,B) are distinct.

第一行包含两个整数N和M,N代表布达佩斯的节点个数,M代表边的个数。节点编号从1到N。1代表出发点s,N代表终点t。接下来的M行每行三个整数A B L,代表有一条从A到B的长度为L的单向同路。你可以认为A不等于B,也不会有重复的(A,B)对。

输出描述 Output Description

Output the length of a strictly-second-shortest route from s to t. If there are less than two possible lengths for routes from s to t, output −1.

输出从s到t的严格次短路的长度。如果从s到t的路少于2条,输出-1。

样例输入 Sample Input

样例输入1:

4 6

1 2 5

1 3 5

2 3 1

2 4 5

3 4 5

1 4 13

样例输入2:

2 2

1 2 1

2 1 1

样例输出 Sample Output

样例输出1:

11

样例输出2:

3

数据范围及提示 Data Size & Hint

对于样例1:

There are two shortest routes of length 10 (1 → 2 → 4,1 → 3 → 4) and the strictly-second- shortest route is 1 → 2 → 3 → 4 with length 11.

对于样例2:

The shortest route is 1 → 2 of length 1, and the strictly-second route is 1 → 2 → 1 → 2 of length 3.

严格次短路、

 1 #include <cstring>
 2 #include <cstdio>
 3 #include <queue>
 4 
 5 const int N(20000+15);
 6 const int M(100000+5);
 7 int n,hed[N],had[N],sumedge;
 8 struct Edge
 9 {
10     int v,next,w;
11     Edge(int v=0,int next=0,int w=0):
12         v(v),next(next),w(w){}
13 }edge1[M],edge2[M];
14 inline void ins(int u,int v,int w)
15 {
16     edge1[++sumedge]=Edge(v,hed[u],w);
17     hed[u]=sumedge;
18     edge2[sumedge]=Edge(u,had[v],w);
19     had[v]=sumedge;
20 }
21 
22 bool inq[N];
23 int d1[N],d2[N];
24 void SPFA(int s,int *dis,int *head,Edge *edge)
25 {
26     std::queue<int>que;
27     for(int i=1;i<=n;i++)
28         dis[i]=0x3f3f3f3f,inq[i]=0;
29     dis[s]=0; que.push(s);
30     for(int u,v;!que.empty();)
31     {
32         u=que.front(); que.pop(); inq[u]=0;
33         for(int i=head[u];i;i=edge[i].next)
34         {
35             v=edge[i].v;
36             if(dis[v]>dis[u]+edge[i].w)
37             {
38                 dis[v]=dis[u]+edge[i].w;
39                 if(!inq[v]) inq[v]=1,que.push(v);
40             }
41         }
42     }
43 }
44 
45 inline void read(int &x)
46 {
47     x=0; register char ch=getchar();
48     for(;ch>'9'||ch<'0';) ch=getchar();
49     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
50 }
51 
52 int AC()
53 {
54     int m;
55     read(n),read(m);
56     for(int u,v,w;m--;ins(u,v,w))
57         read(u),read(v),read(w);
58     SPFA(1,d1,hed,edge1);
59     SPFA(n,d2,had,edge2);
60     int ans=0x3f3f3f3f;
61     for(int u=1;u<=n;u++)
62     {
63         for(int v,i=hed[u];i;i=edge1[i].next)
64         {
65             v=edge1[i].v;
66             int tmp=d1[u]+d2[v]+edge1[i].w;
67             if(tmp<ans&&tmp>d1[n]) ans=tmp;
68         }
69     }
70     if(ans==0x3f3f3f3f) ans=-1;
71     printf("%d
",ans);
72     return 0;
73 }
74 
75 int Hope=AC();
76 int main(){;}
AC的SPFA

下面可以忽略、

  1 #include <cstring>
  2 #include <cstdio>
  3 #include <queue>
  4 
  5 const int N(20000+15);
  6 const int M(100000+5);
  7 int hed[N],had[N],sumedge;
  8 struct Edge
  9 {
 10     int v,next,w;
 11     Edge(int v=0,int next=0,int w=0):
 12         v(v),next(next),w(w){}
 13 }edge1[M],edge2[M];
 14 inline void ins(int u,int v,int w)
 15 {
 16     edge1[++sumedge]=Edge(v,hed[u],w);
 17     hed[u]=sumedge;
 18     edge2[sumedge]=Edge(u,had[v],w);
 19     had[v]=sumedge;
 20 }
 21 
 22 int dis[N];
 23 bool inq[N];
 24 void SPFA(int s)
 25 {
 26     for(int i=1;i<=s;i++) dis[i]=0x3f3f3f3f;
 27     std::queue<int>que;
 28     dis[s]=0; que.push(s);
 29     for(int u,v;!que.empty();)
 30     {
 31         u=que.front(); que.pop(); inq[u]=0;
 32         for(int i=had[u];i;i=edge2[i].next)
 33         {
 34             v=edge2[i].v;
 35             if(dis[v]>dis[u]+edge2[i].w)
 36             {
 37                 dis[v]=dis[u]+edge2[i].w;
 38                 if(!inq[v]) que.push(v),inq[v]=1;
 39             }
 40         }
 41     }
 42 }
 43 
 44 struct Node
 45 {
 46     int now,g;
 47     bool operator < (const Node x)const
 48     {
 49         return dis[now]+g>dis[x.now]+x.g;
 50     }
 51 };
 52 int A_star(int s,int t,int k)
 53 {
 54     if(dis[s]==0x3f3f3f3f) return -1;
 55     int ret=0x3f3f3f3f,cnt=0;
 56     std::priority_queue<Node>que;
 57     Node u,v; u.now=s; u.g=0;
 58     que.push(u);
 59     for(;!que.empty();)
 60     {
 61         u=que.top(); que.pop();
 62         if(cnt>k) return -1;
 63         if(u.now==t)
 64         {
 65             if(ret!=u.g)
 66             {
 67                 ret=u.g;
 68                 if(++cnt==2)
 69                       return ret;
 70             }
 71         }
 72         for(int i=hed[u.now];i;i=edge1[i].next)
 73         {
 74             v.now=edge1[i].v;
 75             v.g=u.g+edge1[i].w;
 76             que.push(v);
 77         }
 78     }
 79     return -1;
 80 }
 81 
 82 inline void read(int &x)
 83 {
 84     x=0; register char ch=getchar();
 85     for(;ch>'9'||ch<'0';) ch=getchar();
 86     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
 87 }
 88 
 89 int AC()
 90 {
 91     int n,m,k;
 92     read(n),read(m);k=m;
 93     for(int u,v,w;m--;ins(u,v,w))
 94         read(u),read(v),read(w);
 95     SPFA(n);
 96     printf("%d
",A_star(1,n,k));
 97     return 0;
 98 }
 99 
100 int Hope=AC();
101 int main(){;}
爆栈的Astar
 1 #include <cstdio>
 2 #include <queue>
 3 
 4 using namespace std;
 5 
 6 const int INF(0x3f3f3f3f);
 7 const int N(20000+105);
 8 const int M(100000+5);
 9 
10 int m,n,head[N],sumedge;
11 struct Edge
12 {
13     int v,next;
14     long long w;
15     Edge(int v=0,int next=0,long long w=0):
16         v(v),next(next),w(w){}
17 }edge[M<<1];
18 inline void ins(int u,int v,long long w)
19 {
20     edge[++sumedge]=Edge(v,head[u],w);
21     head[u]=sumedge;
22 }
23 
24 struct Node
25 {
26     int now;
27     long long dis;
28     bool operator < (const Node &x) const
29     {
30         return dis>x.dis;
31     }
32 };
33 
34 bool vis[N];
35 long long d1[N],d2[N];
36 #define swap(a,b) {long long tmp=a;a=b;b=tmp;}
37 inline void Dijkstar()
38 {
39     for(int i=1;i<=n;i++) d1[i]=d2[i]=INF;
40     priority_queue<Node>que; Node u,to;
41     u.dis=d1[1]=0; vis[1]=1;
42     u.now=1; que.push(u);
43     for(int dis,v;!que.empty();)
44     {
45         u=que.top();que.pop();
46         if(u.dis>d2[u.now]) continue;
47         for(int i=head[u.now];i;i=edge[i].next)
48         {
49             v=edge[i].v;
50             dis=u.dis+edge[i].w;
51             if(dis<d1[v])
52             {
53                 swap(dis,d1[v]);
54                 to.now=v;
55                 to.dis=d1[v];
56                 que.push(to);
57             }
58             if(dis>d1[v]&&dis<d2[v])
59             {
60                 d2[v]=dis;
61                 to.dis=d2[v];
62                 to.now=v;
63                 que.push(to);
64             }
65         }
66     } 
67 }
68 
69 inline void read(int &x)
70 {
71     x=0; register char ch=getchar();
72     for(;ch>'9'||ch<'0';) ch=getchar();
73     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
74 }
75 
76 int AC()
77 {
78 
79     read(n),read(m);
80     for(int v,u,w;m--;ins(u,v,(long long)w))
81         read(u),read(v),read(w);
82     Dijkstar();
83     if(d2[n]==d1[n]) d2[n]=-1;
84     printf("%lld
",d2[n]);
85     return 0;
86 }
87 
88 int I_want_AC=AC();
89 int main(){;}
不能输出-1的Dijkstra
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
原文地址:https://www.cnblogs.com/Shy-key/p/7469723.html