题意:
就是使不大于k条路的权值变为零后求最短路
解析:
d[i][j]表示使j条路变为权值后从起点到点i的最短路径
这题不能用spfa做 tle
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <cctype> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <bitset> #define rap(i, a, n) for(int i=a; i<=n; i++) #define rep(i, a, n) for(int i=a; i<n; i++) #define lap(i, a, n) for(int i=n; i>=a; i--) #define lep(i, a, n) for(int i=n; i>a; i--) #define rd(a) scanf("%d", &a) #define rlld(a) scanf("%lld", &a) #define rc(a) scanf("%c", &a) #define rs(a) scanf("%s", a) #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 100100, INF = 0x3f3f3f3f; int n, m, k; int vis[maxn][15]; int d[maxn][15]; map<int, map<int, int> > t; struct edge{ int u,v, d; edge(int u,int v,int d) { this->u = u; this->v = v; this->d = d; } }; vector<edge> Edge; vector<int> G[maxn<<1]; struct node{ int u, d, y; node(int d,int u, int y) { this->d = d; this->u = u; this->y = y; } bool operator < (const node& a) const { return d > a.d; } }; void add(int u,int v,int d) { Edge.push_back(edge(u,v,d)); G[u].push_back(Edge.size()-1); } void dijkstra(int s) { priority_queue<node> Q; mem(d, INF); d[s][0] = 0; mem(vis,0); Q.push(node(0, s, 0)); while(!Q.empty()) { node x = Q.top();Q.pop(); int u = x.u; int y = x.y; if(vis[u][y]) continue; vis[u][y] = 1; for(int i=0;i<G[u].size();i++) { edge e = Edge[G[u][i]]; if(d[e.v][y] > d[u][y] + e.d) { d[e.v][y] = d[u][y] + e.d; Q.push(node(d[e.v][y],e.v, y)); } if(y + 1 <= k && d[e.v][y+1] > d[u][y]) { d[e.v][y+1] = d[u][y]; Q.push(node(d[e.v][y+1], e.v, y+1)); } } } } int main() { int T; rd(T); while(T--) { t.clear(); Edge.clear(); for(int i=0; i<maxn; i++) G[i].clear(); rd(n), rd(m), rd(k); int u, v, w; for(int i=0; i<m; i++) { rd(u), rd(v), rd(w); if(!t[u][v] || t[u][v] > w) t[u][v] = w; } for(int i=1; i<=n; i++) for(map<int, int>::iterator it = t[i].begin(); it!=t[i].end(); it++) add(i, it->first, it->second); dijkstra(1); int mind = INF; for(int i=0; i<=k; i++) mind = min(mind, d[n][i]); cout<< mind <<endl; } return 0; }