Gym - 101628F Find the Inn dijkstra,读边时计算新权值

题意: 给n个点m条边及每条边所花费的时间,经过给定的p个点时会停留k秒,要求在t秒内从1号点走到n号点,若可以走到输出最短时间,若不行输出-1.。

题解:读取边时,将每个点停留的时间加到以其为终点的边的花费上。比如边1 2 10,且2是给定的停留点(设停留5s),则读入这条边时按 1 2 15 读入,然后正常dijkstra即可。

坑点:单位有分有秒/有向边/参数貌似很多。由于一直找不到wa在哪里,先是怀疑爆int,然后把那个多余的map简化成了bool数组,又把输出时的if,else优化了一下,(只是把代码弄得短一些,然并卵)最后怀疑邻接链表有问题,全部改成链式前向星ORZ,依然并卵。又怀疑dijkstra要加vis数组,依然并卵。最后改priority_queue,先发现prioirity_queue<int,vector<int>,greater<int> > 报错,只能用了一个point结构体重载+-,然而并没有什么卵用!!最后发现自己多写了一行T*=60 Orz

 

 

 

ac代码:

#include<iostream>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const ll maxn = 1e5 + 5;
ll n, m, k, p;
long long T;
vector< pair<ll, ll> > E[maxn];
ll d[maxn];
map<ll, ll> pine;
void init() {
    for (ll i = 0; i <maxn; i++) E[i].clear(), d[i] = 2e18;
}
int  main()
{

    while (cin >> n >> m >> T >> k >> p) {
        //T *= 60;
        for (ll i = 0; i<p; i++) {
            ll x; cin >> x; pine[x]++;
        }

        init();
        for (ll i = 0; i < m; i++) {
            ll x, y;
            long long z;
            cin >> x >> y >> z;
            z *= 60;

            if (pine.count(y))
                E[x].push_back(make_pair(y, z + k));
            else E[x].push_back(make_pair(y, z));
        }

        ll s = 1, t = n;
        priority_queue<pair<ll, ll> > Q;
        d[s] = 0; Q.push(make_pair(-d[s], s));
        while (!Q.empty()) {
            ll now = Q.top().second;
            Q.pop();

            for (ll i = 0; i < E[now].size(); i++)
            {
                ll v = E[now][i].first;
                if (d[v] > d[now] + E[now][i].second) {
                    d[v] = d[now] + E[now][i].second;

                    Q.push(make_pair(-d[v], v));
                }
            }
        }
        
        if (d[t] == 2e18 || d[t] > T * 60)cout << -1 << endl;
        else cout << d[t] << endl;

    }
}

一度改得面目全非:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
const long long maxn = 100005;
typedef long long ll;
ll n, m, k, p,T;
ll pine[maxn];
ll head[maxn], now,dis[maxn],vis[maxn];
struct edge {
    ll to, next, val;
}e[2*maxn];
void addedge(ll x, ll y, ll z) {
    e[++now].to = y, e[now].val = z, e[now].next = head[x], head[x] = now;
}
struct point {
    ll val, id;
    point(ll id, ll val) :id(id), val(val) {}
    bool operator <(const point &x) const {
        return val > x.val;
    }
};
void dij(ll s) {
    priority_queue<point>Q;
    Q.push(point(s, 0));
    vis[s] = 1;
    dis[s] = 0;
    while (!Q.empty()) {
        ll cur = Q.top().id;
        Q.pop();
        vis[cur] = 1;
        for (ll i = head[cur]; i != -1; i = e[i].next) {
            ll id = e[i].to;
            if (!vis[id] && (dis[cur] + e[i].val < dis[id] || dis[id] == -1)) {
                dis[id] = dis[cur] + e[i].val;
                Q.push(point(id, dis[id]));
            }
        }
    }

}
int main(){

    scanf("%lld%lld%lld%lld%lld", &n, &m, &T, &k, &p);
    memset(head, -1, sizeof(head));
    memset(dis, -1, sizeof(dis));
    //T *= 60;
    for (ll i = 0; i<p; i++) {
        ll x; scanf("%lld", &x); pine[x] = 1;
    }
    for (ll i = 0; i < m; i++) {
        ll x, y;
        long long z;
        scanf("%lld%lld%lld", &x, &y, &z);
        z *= 60;
        addedge(x, y, k*pine[y] + z);
    }
    dij(1);
    if (dis[n] <= T * 60)    printf("%lld", dis[n]);
    else printf("-1");
}

 



posted @ 2018-03-08 19:10  SuuTTT  阅读(233)  评论(0编辑  收藏  举报