原题: http://acm.zjnu.edu.cn/CLanguage/showproblem?problem_id=2255
题意:
n点m无向边,终点为点n。有k个东西,给出每个东西的位置,以及一个值w。当你得到一个东西,你的路径长度会减少w。只用使用一个东西。
问有多少个点可以在不增加路径长度的前提下拿到东西。
解析:
这题很水,就是有句话看不懂:but only if the amount of time this adds to her path is at most the yumminess of the haybale she visits.翻译过来是:增加的时间最多为那个值……真的看不懂。
先做一遍dijkstra,得出d最短路dis,然后将所有有草的地方的dis减去对应w值。看看以这些点为起点时,其他点能不能达到或者小于之前的dis。这个过程相当于先走到这些点再去终点。
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(register int i=a;i<=b;i++)
#define repp(i,a,b) for(register int i=a;i>=b;i--)
#define mmm(p) memset(p,0,sizeof p)
#define pill pair<int,int>
#define debug(i) printf("#%d\n",i)
typedef long long LL;
int read(){ int ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
const int maxn=5e4+4,maxm=2e5+8;
int n,m,k;
int head[maxn],to[maxm],nex[maxm],now;
LL val[maxm];
void add(int a,int b,LL v){
nex[++now]=head[a];head[a]=now;
to[now]=b;val[now]=v;
}
struct node{
int id;LL val;
node(){}
node(int id,LL val):id(id),val(val){}
bool operator<(const node &r)const{
return val>r.val;
}
};
priority_queue<node>Q;
LL dis[maxn];
bool vis[maxn];
void dijks(){
memset(dis,0x3f,sizeof dis);
dis[n]=0;Q.push(node(n,0));
while(!Q.empty()){
int id=Q.top().id;Q.pop();
vis[id]=1;
for(int i=head[id];i;i=nex[i]){
int u=to[i];
if(!vis[u]&&dis[u]>dis[id]+val[i]){
dis[u]=dis[id]+val[i];
Q.push(node(u,dis[u]));
}
}
}
}
LL w[maxn];
void dijks2(){
while(!Q.empty())Q.pop();
memset(vis,0,sizeof(vis));
rep(i,1,n-1){
if(!w[i])w[i]=0x3f3f3f3f;
else w[i]=dis[i]-w[i],Q.push(node(i,w[i]));
}
while(!Q.empty()){
int id=Q.top().id;Q.pop();
vis[id]=1;
for(int i=head[id];i;i=nex[i]){
int u=to[i];
if(!vis[u]&&w[u]>w[id]+val[i]){
w[u]=w[id]+val[i];
Q.push(node(u,w[u]));
}
}
}
}
int main(){
n=read(),m=read(),k=read();
rep(i,1,m){
int a=read(),b=read();LL v=(LL)read();
add(a,b,v);
add(b,a,v);
}
rep(i,1,k){
int p=read();LL v=(LL)read();w[p]=max(w[p],v);
}
dijks();
dijks2();
rep(i,1,n-1){
if(w[i]<=dis[i])printf("1\n");
else printf("0\n");
}
}