Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 551 | Accepted: 171 |
Description
At the joint of a tunnel and a cave, there is a door. From time to time, the terrorists close a tunnel by shutting the two doors at the two ends, and "clean" the tunnel. It is still a mystery how they clean the tunnel. However, we know that if a person (or any living creature) is trapped in the tunnel when it is being cleaned, then the person (or the living creature) will die. After a cleaning of the tunnel is finished, the door will open, and the tunnel can be used again.
Now the intelligence servicemen have found out which cave the leader is hiding,and moreover, they know the schedule of the cleaning of the tunnels. Jing Raider is going to go into the cave and catch the leader. You need to help him find a route so that he can get to that cave in the shortest time. Be careful not to be trapped in a tunnel when it is being cleaned.
Input
The next m lines are information of the m tunnels: Each line is a sequence of at most 35 integers separated by at least one space. The first two integers are the caves that are the ends of the corresponding tunnel. The third integer is the time needed to travel from one end of the tunnel to the other. This is followed by an increasing sequence of positive integers (each integer is at most 10000) which are alternately the closing and the opening times of the tunnel. For example, if the line is
10 14 5 6 7 8 9
then it means that the tunnel connects cave 10 and cave 14, it takes 5 units of time to go from one end to the other. The tunnel is closed at time 6, opened at time 7, then closed again at time 8, opened again at time 9. Note that the tunnel is being cleaned from time 6 to time 7, and then cleaned again from time 8 to time 9. After time 9, it remains open forever.
If the line is
10 9 15 8 18 23
then it means that the tunnel connects cave 10 and cave 9, it takes 15 units of time to go from one end to the other. The tunnel is closed at time 8, opened at time 18,then closed again at time 23. After time 23, it remains closed forever.
The next test case starts after the last line of the previous case. A 0 signals the end of the input.
Output
Sample Input
2 2 1 2 1 2 5 4 10 14 20 24 30 1 2 6 2 10 22 30 6 9 1 6 1 2 6 5 10 1 3 7 8 20 30 40 2 4 8 5 13 21 30 3 5 10 16 25 34 45 2 5 9 22 32 40 50 3 4 15 2 8 24 34 4 6 10 32 45 56 65 5 6 3 2 5 10 15 2 3 5 2 9 19 25 2 2 1 2 1 2 7 6 9 12 1 2 9 8 12 19 0
Sample Output
16 55 *
Source
sfpa 算法,
知道怎么更新就好了
队列的点出队列后,判断它能否更新临近的点
就是在隧道开开启的时间段他能否有时间通过
1A 比较开心的
#include <iostream> #include <stdio.h> #include <queue> #include <stack> #include <set> #include <vector> #include <math.h> #include <string.h> #include <algorithm> using namespace std; #define N 52 #define Max 1000000000 structnode { int to; int cost; int next; int n; int t[43]; }Eg[1002]; int v[N]; char ch[1002]; int n,m,s,t; int nu; int rc [N]; void del(char *ch) { int i; int id=0; int t=0; for(i=0;ch[i]!='\0';i++) if(ch[i]>='0'&&ch[i]<='9') t=t*10+ch[i]-'0'; else if(t) { rc[id++]=t; t=0; } if(t) rc[id++]=t; int a=rc[0],b=rc[1],c=rc[2]; Eg[nu].to=b; Eg[nu].n=id-2; Eg[nu].cost=c; Eg[nu].next=v[a]; v[a]=nu++; Eg[nu].to=a; Eg[nu].n=id-2; Eg[nu].cost=c; Eg[nu].next=v[b]; v[b]=nu; a=1; for(i=3;i<id;i++) { Eg[nu-1].t[a]=rc[i]; Eg[nu].t[a++]=rc[i]; } Eg[nu-1].t[a]=Max;//自加了个Max代表无穷远了 Eg[nu].t[a++]=Max; nu++; } int dis[N]; int main() { int i,k,a; while(scanf("%d %d %d %d",&n,&m,&s,&t)==4&&n) { memset(v,-1,sizeof(v)); nu=0;gets(ch); while(m--) { gets(ch); del(ch); } if(s==t) { printf("0\n");continue;} for(i=1;i<=n;i++) dis[i]=Max; dis[s]=0; memset(rc,0,sizeof(rc)); queue<int>Q; Q.push(s);rc[s]=1; int time,len; while(!Q.empty()) { a=Q.front();Q.pop(); rc[a]=0; for(i=v[a];i!=-1;i=Eg[i].next) { for(k=1;k<=Eg[i].n;k++) if(k%2) { len=Eg[i].t[k]-Eg[i].t[k-1]; time=max(dis[a],Eg[i].t[k-1])+Eg[i].cost; if(len>=Eg[i].cost&&Eg[i].t[k]>=time&&time<dis[Eg[i].to])//可以更新的条件 { dis[Eg[i].to]=time; if(!rc[Eg[i].to]) Q.push(Eg[i].to); break; } } } } if(dis[t]==Max) printf("*\n"); else printf("%d\n",dis[t]); } return 0; }