在无限失败中获得成功,什么wrong,什么TLE,什么RE都出现过,错了几十次的说。。
现在在这里说明下我的理解。。不知道有没错误。。
题意:这是关于时空穿梭的图论题?题目告诉我们n个星球,m个路径,每条路径有起点,终点,起始时间,终结时间;最后一行是开始地点,目的地,开始时间和叛徒所在时间。当然我就这么理解了,英语四级425的货,没办法理解具体单词。。这题的特色就是时间可以倒流,十分幻想啊(''),而且人物不能再相同地点和相同时间下出现。
解法:bfs的结果,当直接来会TLE啊,RE啊,(ˇˍˇ) 我就是这样过来的。主要缩减的地方是在A时刻到达C地点的时候,开车时间B(B>=A)的路线肯定可以过去,可以每条路在BFS中只用去一遍,排序后省略遍历这部分,这里就能缩减遍历的时间,具体在代码中指出。还有就是我没用vector来存路径,不知道有没效果的说,一开始存vector的时候RE了。
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e5+10;
struct node{
int from,to;
int t1,t2;
int num;
}e[maxn];
int end_where,end_time,start_where,start_time,sum;
int first[maxn],last[maxn],pre[maxn],mark[maxn];
int cmp(node a,node b)
{
if(a.from==b.from)return a.t1>b.t1;//开车时间从大到小排序下
return a.from<b.from;
}
void show(int a)//递归输出结果
{
sum++;
if(pre[a]==-1)
{
printf("%d\n",sum);
printf("%d",a);
return;
}
show(pre[a]);
printf(" %d",a);
}
void bfs(int m)
{
queue<int>q;
int i,j,k,v;
q.push(m);//队列里加的是序号,应该能简约点空间吧,maybe
mark[m]=1;
while(!q.empty())
{
v=q.front();
q.pop();
for(i=first[e[v].to];i<last[e[v].to];i++)
{
if(mark[i])continue;
if(e[v].t2>e[i].t1){first[e[v].to]=i;break;}//排序过之后,后面的必定不符合,开始点也变换成这点
mark[i]=1;
pre[e[i].num]=e[v].num;//记录路径
if(e[i].to==end_where&&e[i].t2<=end_time)
{
sum=0;
show(e[i].num);
printf("\n");
return;
}
q.push(i);
}
}
printf("Impossible\n");
}
int main()
{
//freopen("D:\\output.txt","r",stdin);
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j,k;
memset(first,0,sizeof(first));
memset(last,0,sizeof(last));
memset(mark,0,sizeof(mark));
for(i=0;i<m;i++)
{
scanf("%d%d%d%d",&e[i].from,&e[i].to,&e[i].t1,&e[i].t2);
e[i].num=i+1;
}
scanf("%d%d%d%d",&start_where,&end_where,&start_time,&end_time);
if(start_where==end_where&&start_time<=end_time){printf("0\n");continue;}
sort(e,e+m,cmp);//先起点排序,之后根据开车时间排序
for(i=0;i<m;i++)
{
if(i==0||e[i].from!=e[i-1].from)first[e[i].from]=i; //起点在e[i].from的段,在[first[e[i].from],last[e[i].from])间
if(i==m-1||e[i].from!=e[i+1].from)last[e[i].from]=i+1;
}
e[m].to=start_where;
e[m].t2=start_time;
e[m].num=-1;
bfs(m);
}
return 0;
}
/*
3 3
1 2 10 20
3 2 11 19
1 3 11 10
1 2 10 19
3 3
1 2 20 10
2 1 30 10
1 3 40 30
1 3 10 30
2 2
1 1 30 10
1 2 20 10
1 2 30 10
3 3
1 2 20 10
2 1 10 15
1 3 15 10
1 3 20 10
3 5
1 2 10 20
2 1 20 10
1 2 10 20
2 1 20 10
1 3 10 30
1 3 10 30
3 3
1 2 10 20
2 1 20 5
1 3 10 30
1 3 10 30
*/