题目大意:给出一张无向图,给出一个数值m,求出从1到N的前k短路的长度和>=数值m。
思路:注意!不能使用priority_queue,否则你会死的很惨。。为了解惑,我去找了当年SD省选的原题,分明空间是256M,为什么BZOJ和BASHUOJ上都是64M??卡pq有意思么???
思路很简单,就是按顺序求出这张图的前k短路,然后当m减成负数的时候就返回。
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 400010 #define MAXP 5010 using namespace std; struct Complex{ double g,h; int pos; Complex(double _,double __,int ___):g(_),h(__),pos(___) {} bool operator <(const Complex &a)const { return g + h > a.g + a.h; } }now(0,0,0); int points,edges; double ceil; int head[MAXP],tail[MAXP],total; int next[MAX],aim[MAX]; double length[MAX]; double f[MAXP]; bool v[MAXP]; int cnt[MAXP]; inline void Add(int x,int y,double len) { next[++total] = head[x]; aim[total] = y; length[total] = len; head[x] = total; next[++total] = tail[y]; aim[total] = x; length[total] = len; tail[y] = total; } void SPFA() { static queue<int> q; while(!q.empty()) q.pop(); memset(f,0x43,sizeof(f)); f[points] = .0; q.push(points); while(!q.empty()) { int x = q.front(); q.pop(); v[x] = false; for(int i = tail[x]; i; i = next[i]) if(f[aim[i]] > f[x] + length[i]) { f[aim[i]] = f[x] + length[i]; if(!v[aim[i]]) v[aim[i]] = true,q.push(aim[i]); } } } int Astar(int k) { static priority_queue<Complex> q; now = Complex(.0,f[1],1); q.push(now); while(!q.empty()) { now = q.top(); q.pop(); if(++cnt[now.pos] > k) continue; if(now.pos == points) { if(ceil -= now.g,ceil <= 0) return cnt[now.pos] - 1; k = cnt[points] + static_cast<int>(ceil / now.g) + 1; } for(int i = head[now.pos]; i; i = next[i]) if(cnt[aim[i]] <= k) q.push(Complex(now.g + length[i],f[aim[i]],aim[i])); } return 0; } int main() { cin >> points >> edges >> ceil; for(int x,y,i = 1; i <= edges; ++i) { double len; scanf("%d%d%lf",&x,&y,&len); Add(x,y,len); } SPFA(); cout << Astar(static_cast<int>(ceil / f[1]) + 1) << endl; return 0; }