看discuz里有人用spfa做的,这题没想通怎么用spfa,再怎么一次spfa觉得不行啊,多次spfa不会超时么
我是用的bfs搜的,自己写的堆,效率一般
这题有环,重边,所以邻接矩阵是不行的,我用的是数组模拟邻接表
没加优化,188ms过的
#include <stdio.h> #define MAX 10001 #define INF 1<<15 struct node { int d; int length; int cost; int next; }street[MAX]; int head[MAX],city[MAX*5][3]; void heap(int n,int N) { int x=n,x1=2*n+1,x2=2*n+2; if(x1<N && (city[x1][0]<city[x][0] || (city[x1][0]==city[x][0] && city[x1][1]< city[x][1]))) { x=x1; } if(x2<N && (city[x2][0]<city[x][0] || (city[x2][0]==city[x][0] && city[x2][1]< city[x][1]))) { x=x2; } if(x!=n) { city[x][1]^=city[n][1]; city[x][0]^=city[n][0]; city[x][2]^=city[n][2]; city[n][1]^=city[x][1]; city[n][0]^=city[x][0]; city[n][2]^=city[x][2]; city[x][1]^=city[n][1]; city[x][0]^=city[n][0]; city[x][2]^=city[n][2]; heap(x,N); } return; } void buildheap(int N) { int i=0; for(;i<N>>1;++i) { heap(i,N); } return; } int bfs(int N, int cost) { int i=0,rearp=1; city[0][0]=0; city[0][1]=0; city[0][2]=1; while(0 != rearp) { if(N == city[0][2] && city[0][1]<=cost) { return city[0][0]; } i=head[city[0][2]]; while(-1 != i) { if(cost >= city[0][1]+street[i].cost) { city[rearp][0]=city[0][0]+street[i].length; city[rearp][1]=city[0][1]+street[i].cost; city[rearp++][2]=street[i].d; } i=street[i].next; } city[0][0]=city[--rearp][0]; city[0][1]=city[rearp][1]; city[0][2]=city[rearp][2]; buildheap(rearp); } return -1; } int main() { int R=0,i=0,K=0,N=0,x; scanf("%d%d%d",&K,&N,&R); for(i=0;i<=N;++i) { head[i]=-1; } for(i=0;i<R;++i) { scanf("%d %d %d %d",&x,&street[i].d,&street[i].length,&street[i].cost); street[i].next=head[x]; head[x]=i; } printf("%d\n",bfs(N,K)); }
再贴一个无聊STL写的,反而代码更长了,有点纠结编程风格了
#include <iostream>
#include <queue>
#include <list>
using namespace std;
const int MAX = 10001;
const int INF = 1<<15;
class myqueue
{
public:
myqueue():cost(0),length(0),city(0){};
myqueue(int cost=0,int length=0,int city=0);
myqueue(const myqueue &);
friend bool operator <(const myqueue&, const myqueue &);
int cost;
int length;
int city;
};
bool operator < (const myqueue &_b,const myqueue &_a)
{
if (_b.length > _a.length)
{
return true;
}
else
{
if (_b.length == _a.length && _b.cost > _a.cost)
{
return true;
}
else
{
return false;
}
}
}
myqueue::myqueue(const myqueue &_a)
{
cost=_a.cost;
length=_a.length;
city=_a.city;
}
myqueue::myqueue(int cost,int length,int city):cost(cost),length(length),city(city){}
class node
{
public:
friend istream& operator >>(istream &,node &);
node();
node(const node &);
int distination;
int length;
int cost;
};
node::node():distination(0),length(0),cost(0){}
node::node(const node & _a)
{
distination = _a.distination;
length = _a.length;
cost = _a.cost;
}
istream & operator >>(istream &input, node &_a)
{
input>>_a.distination>>_a.length>>_a.cost;
return input;
}
vector<list<node>> citys;
int bfs(int N,int K)
{
priority_queue<myqueue> queue;
queue.push(myqueue(0,0,1));
while(!queue.empty())
{
int now_city=queue.top().city;
int now_cost=queue.top().cost;
int now_length=queue.top().length;
if(N == now_city && K >= now_cost)
{
return now_length;
}
queue.pop();
for(list<node>::const_iterator itr=citys[now_city].begin();
itr!=citys[now_city].end();++itr)
{
if(itr->cost+now_cost <= K)
{
queue.push(myqueue (itr->cost+now_cost,itr->length+now_length,itr->distination));
}
}
}
return -1;
}
int main()
{
int R=0,K=0,N=0;
cin>>K>>N>>R;
for(int i=0;i<=N;++i)
{
citys.push_back(list<node>());
}
for(int i=0;i<R;++i)
{
node a;
int x;
cin>>x>>a;
citys[x].push_front(a);
}
cout<<bfs(N,K)<<endl;
}