题目链接:https://nanti.jisuanke.com/t/31001
解题心得:
- 一个BZOJ的原题,之前就写过博客了。
- 比赛的时候遇到这个题第一个反应就是原题,然后用了以前的代码,WA:单向边,以前代码上是双向边。TLE:这个题出题人还卡了一下网格图。
#include <stdio.h> #include <cstring> #include <algorithm> #include <queue> #include <vector> using namespace std; typedef long long ll; typedef pair<ll,ll> P; const int maxn = 1e6+100; const ll INF = 1e12; ll n, m, k, S, T; struct edge { ll to, len; edge(ll to1, ll len1): to(to1), len(len1){}; }; struct NODE { ll len, pos, c; bool friend operator < (NODE a, NODE b) { return a.len > b.len; } NODE (ll len1, ll pos1, ll c1): len(len1), pos(pos1), c(c1){}; }; vector <edge> ve[maxn]; ll dis[11][maxn]; void add_edge(ll u, ll v, ll len) { ve[u].push_back(edge(v, len)); } void init() { for(int i=0;i<11;i++) for(int j=0;j<maxn;j++) dis[i][j] = INF; scanf("%lld%lld%lld",&n,&m,&k); for(int i=0;i<=n;i++) ve[i].clear(); S = 1, T = n; for(int i=0;i<m;i++) { ll u, v, len; scanf("%lld%lld%lld",&u, &v, &len); add_edge(u, v, len); } } void dij() { priority_queue <NODE> qu; qu.push(NODE(0, S, 0)); dis[0][S] = 0; while(!qu.empty()) { NODE now = qu.top(); qu.pop(); ll u = now.pos; for(int i=0;i<ve[u].size();i++) { ll v = ve[u][i].to; ll len = ve[u][i].len; ll c = now.c; if(dis[c][v] > dis[c][u]+len) { dis[c][v] = dis[c][u] + len; qu.push(NODE(dis[c][v], v, c)); } } ll c = now.c; if(c < k) { for (int i = 0; i < ve[u].size(); i++) { ll v = ve[u][i].to; if(dis[c+1][v] > dis[c][u]) { dis[c+1][v] = dis[c][u]; qu.push(NODE(dis[c][u], v, c+1)); } } } } } void min_path() { dij(); ll Min = INF; for(int i=0;i<=k;i++) { Min = min(Min, dis[i][T]); } printf("%lld ", Min); } int main() { int t; scanf("%d",&t); while(t--) { init(); min_path(); } }