n个点m条边的有向图,每条边有距离跟花费两个参数,求1->n花费在K以内的最短路。
直接优先队列bfs暴力搞就行了,100*10000个状态而已。节点扩充的时候,dp[i][j]表示到达第i点花费为j时的最短路。没加优化16ms过,不知道discuss里面说bfs超时是怎么回事。。。。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<fstream> #include<sstream> #include<bitset> #include<vector> #include<string> #include<cstdio> #include<cmath> #include<stack> #include<queue> #include<stack> #include<map> #include<set> #define FF(i, a, b) for(int i=a; i<b; i++) #define FD(i, a, b) for(int i=a; i>=b; i--) #define REP(i, n) for(int i=0; i<n; i++) #define CLR(a, b) memset(a, b, sizeof(a)) #define debug puts("**debug**") #define LL long long #define PB push_back #define eps 1e-10 using namespace std; const int maxn = 111; const int INF = 1e9; int n, m, K, dp[maxn][10001]; struct Edge { int from, to, dist, cost; }; vector<int> G[maxn]; vector<Edge> edges; void init() { FF(i, 1, n+1) { G[i].clear(); REP(j, K+1) { if(i == 1) dp[i][j] = 0; else dp[i][j] = INF; } } edges.clear(); } void add(int u, int v, int d, int c) { edges.PB((Edge){u, v, d, c}); int nc = edges.size(); G[u].PB(nc-1); } struct Node { int u, d, c; bool operator < (const Node& rhs) const { return d > rhs.d; } }; int bfs() { priority_queue<Node> q; q.push((Node){1, 0, 0}); while(!q.empty()) { Node x = q.top(); q.pop(); if(x.u == n) return x.d; int nc = G[x.u].size(); REP(i, nc) { Edge e = edges[G[x.u][i]]; if(e.cost + x.c > K) continue; if(dp[e.to][x.c+e.cost] > x.d+e.dist) { dp[e.to][x.c+e.cost] = x.d+e.dist; q.push((Node){e.to, x.d+e.dist, x.c+e.cost}); } } } return -1; } int main() { while(~scanf("%d%d%d", &K, &n, &m)) { init(); int a, b, c, d; REP(i, m) { scanf("%d%d%d%d", &a, &b, &c, &d); if(a != b) add(a, b, c, d); } printf("%d ", bfs()); } return 0; }