USACO23FEB-Silver C
题目来源(From)
洛谷:USACO23FEB Moo Route II S(C) - 题目
SPOJ:USACO23FEB Moo Route II S(C) - 题目
题解:USACO23FEB Moo Route II S(C) - 题解
题目(Problem)
题目描述
全国有
也就是说,如果
-1
。
输入格式
第一行输入两个整数
接下来的
接下来一行,包含
输出格式
输出-1
。
样例
输入数据 1
3 3
1 0 2 10
2 11 2 0
2 1 3 20
10 1 10
输出数据 1
0
0
20
样例1说明
请注意,这条路线经过
输入数据 2
3 3
1 0 2 10
2 10 2 0
2 1 3 20
10 1 10
输出数据 2
0
10
-1
样例2说明
在这种情况下,
数据规模与约定
- 测试点
: ;对于所有 ,所有航班起飞后到达。 - 测试点
: - 测试点
:没有其它约定。
题解(Solution)
直接抄的题解:
一个重要的性质:每个航班是不会被重复乘坐的。因为,不管你在什么前提下乘坐了某个航班,这个航班对你造成的影响是完全相同的。
这让
从
这样做是
将一个机场出发的航班按
依旧是
因为,我们会多次访问一个机场,每次都要枚举它的大多数出边(其中绝大多数枚举都是重复的)。考虑存储
代码(Code)
#include<bits/stdc++.h>
#include<vector>
#include<queue>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define Rof(i,l,r) for(int i=l;i>=r;i--)
using namespace std;
#define int long long
inline int input(){char c;bool f=false;while(!isdigit(c=getchar()))f=c=='-';int x=c^48;while(isdigit(c=getchar())){x=(((x<<2)+x)<<1)+(c^48);}return f?-x:x;}
const int inf = 0x3f3f3f3f3f3f3f;
const int N = 1012345;
int n,m,a[N];
struct T{int y,st,ed;};
vector<T> ft[N];
int d[N],fir[N];
bitset<N> vst;
void Spfa(int st){
d[st]=-a[1];vst[st]=true;
queue<int> q;q.push(st);
while(q.size()){
int x=q.front();q.pop();
vst[x]=false;
Rof(i,fir[x],0){
T e=ft[x][i];if(e.st < d[x]+a[x]) break;//如果已经超过起飞时间
int y=e.y;
if(d[y]>e.ed){
d[y]=e.ed;
if(vst[y]==0) q.push(y),vst[y]=true;
}fir[x]=i-1;
}
}
}
inline bool cmp(T a,T b){return a.st==b.st?a.ed<b.ed:a.st<b.st;}
signed main(){
string str("c");
freopen((str+".in").c_str(),"r",stdin);
freopen((str+".out").c_str(),"w",stdout);
memset(d,0x3f,sizeof(d));vst.reset();
cin>>n>>m;
For(i,1,m){
int x=input(),st=input(),y=input(),ed=input();
ft[x].push_back({y,st,ed});
}For(x,1,n){
cin>>a[x];
sort(ft[x].begin(),ft[x].end(),cmp);
fir[x]=ft[x].size()-1;
}Spfa(1);printf("0\n");
For(x,2,n) cout<<(d[x]>=inf?-1ll:d[x])<<'\n';
return 0;
}