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