思路:K = 10000,dijkstra复杂度O(nlogn),如果我们把不同点的不同花费拆点,即d[花费][点] = 距离,则被拆为 N*K个点,分成K层,则dijkstra复杂度O(k * (n *logn + m)),复杂度在超时边缘徘徊...
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define ll long long
#define pb push_back
#define fi first
#define se second
const int N = 110;
const int INF = 1e9;
struct node{
int v, w, c;
};
int n, k, m;
vector<node > E[N];
int d[10010][N];
void dijkstra(){
for(int i = 0; i <= 10000; ++i){
for(int j = 1; j <= 100; ++j){
d[i][j] = INF;
}
}
queue<pair<int ,int > > que;
d[0][1] = 0;
que.push(make_pair(0, 1));
while(!que.empty()){
int c = que.front().fi;
int u = que.front().se;
que.pop();
for(int i = 0; i < (int)E[u].size(); ++i){
node e = E[u][i];
if(c + e.c > k) continue;
if(d[c + e.c][e.v] > d[c][u] + e.w){
d[c + e.c][e.v] = d[c][u] + e.w;
que.push(make_pair(c + e.c, e.v));
}
}
}
}
void solve(){
scanf("%d%d%d", &k, &n, &m);
int u, v, w, c;
for(int i = 0; i < m; ++i){
scanf("%d%d%d%d", &u, &v, &w, &c);
E[u].pb({v, w, c});
}
dijkstra();
int ans = INF;
for(int i = 0; i <= k; ++i){
ans = min(ans, d[i][n]);
}
//printf("ans = ");
printf("%d\n", ans == INF ? -1 : ans);
}
int main(){
solve();
//cout << "not error" << endl;
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/4260177/blog/4295715