题目大意:给出一张无向图,给出一个数值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;
}BZOJ 1975 SDOI 2010 魔法猪学院 A*求K短路
原文地址:http://blog.csdn.net/jiangyuze831/article/details/41309383