Fine Dining(最短路应用)

原题: 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");
    }

}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/88551800