Luogu P3946 ことりのおやつ(小鸟的点心) 【最短路】By cellur925

题目传送门

日本的冬天经常下雪。不幸的是,今天也是这样,每秒钟雪的厚度会增加q毫米。

秋叶原共有n个地点,编号从1到n。每个地点在开始的时候的积雪高度为hi。

有m条双向道路连接这些地点,它们的长度分别为wi米。

雪太大,公共交通系统已经停摆了,所以ことり得走路回家。她走路的速度是1m/s。

为了方便地图的绘制,秋叶原的道路规划使得每条道路严格地连接两个不同的地点,并且不会有两条道路连接的地点相同。

每个地点都有一个极限雪高li,单位是毫米,如果到达这个地点的时候,这里的雪的高度高于li则会被困在这个点走不出去,无法成功地走到ことり家。

点心店这个地点的编号是s,ことり家的编号是t。

不考虑点心店和ことり家的雪。

ことり想在g秒内回到家吃点心,越快越好。如果在g秒之内,ことり无法到家,或者她被困在路上了,那么ことり会把wtnap变成她的点心( ・ 8 ・ )

emmm其实真心是个水题。感觉自己做题做傻了,竟然跑一遍最短路之后再判断各点是否满足要求。其实在跑最短路的时候顺便判断一下就好了,如果不满足要求就不把这个点进行松弛了emmm。真·学傻了。

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define maxn 100090
#define maxm 500090

using namespace std;
typedef long long ll;

int n,m,s,t,g,del,tot;
int head[maxn];
ll be[maxn],lim[maxn],dis[maxn];
bool vis[maxn];
struct node{
    int to,next,val;
}edge[maxm*2];

void add(int x,int y,int z)
{
    edge[++tot].to=y;
    edge[tot].next=head[x];
    edge[tot].val=z;
    head[x]=tot;
}

void dijkstra()
{
    priority_queue<pair<int,int> >q;
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0;q.push(make_pair(0,s));
    while(!q.empty())
    {
        int u=q.top().second;q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(1ll*del*min(dis[u]+edge[i].val,dis[v])+be[v]>lim[v]&&v!=t) continue;
            if(dis[v]>dis[u]+edge[i].val)
            {
                dis[v]=dis[u]+edge[i].val;
                q.push(make_pair(-dis[v],v));
            }
        }
    }
}

int main()
{
    scanf("%d%d%d%d%d%d",&n,&m,&s,&t,&g,&del);
    for(int i=1;i<=n;i++)
        scanf("%lld%lld",&be[i],&lim[i]);
    for(int i=1;i<=m;i++)
    {
        int x=0,y=0,z=0;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
    }
    dijkstra();
    if(dis[t]>g)
        {printf("wtnap wa kotori no oyatsu desu!");return 0;}
    printf("%lld",dis[t]);
    return 0;
}

 

posted @ 2018-10-25 14:01  cellur925&Chemist  阅读(165)  评论(0编辑  收藏  举报