5
6 7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2
11
题意
先来了解一下这道题吧,这个题的大致意思很容易明白,就是
给出最高花费 K, 目的地点N, 以及R条从u到v的的长度,已经所
需要的花费。要求算出从1出发,走到N点时,在不超出自己已有
的经费内,找出所需要走的最短的路,如果找不到,输出-1。
看到这道题时,刚开始想用Dijkstra()写了,再加一些优化条件,测试数据挺顺的,可惜还是WA。后来改成优先队列,用了邻接表存了一下各个点的多种情况
f[i].next = head[f[i].u]; //存储上一次出现的位置
head[f[i].u] = i; //存储这次出现的位置
f[i].next = head[f[i].u]; //存储上一次出现的位置
head[f[i].u] = i; //存储这次出现的位置
通过判断点u到v所用的花费和之前的花费之和 是否超出本有的资金,再决定是否进入队列中。
for(int i = head[now.u]; i ; i = f[i].next)
//找到所有和now.s相连的点
if(now.cost + f[i].cost <= K) //注意这里面的i表示的是第几条边
{
tmp.cost = now.cost + f[i].cost;
tmp.u = f[i].v;
tmp.s = now.s + f[i].l;
Q.push(tmp);
}
本题中,首先用结构体存入R条道路中,所给出的信息。然后再用一个结构体保存在寻找过程中所走的最短路口,以及所需要的花费
struct note
{
int u,v,l,cost; //地点u -> v, 距离 花费
int next;
}f[10010];
struct node
{
int u,s,cost;
friend bool operator < (node a,node b)
{
return a.s > b.s;
}
};
废话就不多说了,直接了解一下代码吧
#include
#include
#include
#include
using namespace std;
int N,K,R;
struct note
{
int u,v,l,cost;
int next;
}f[10010];
int head[10010];
struct node
{
int u,s,cost;
friend bool operator < (node a,node b)
{
return a.s > b.s;
}
};
int bfs()
{
priority_queueQ;
node now,tmp;
now.u = 1;
now.s = 0;
now.cost = 0;
Q.push(now);
while(!Q.empty())
{
now = Q.top();
Q.pop();
if(now.u == N)
return now.s;
for(int i = head[now.u]; i ; i = f[i].next) //找到所有和now.s相连的点
if(now.cost + f[i].cost <= K) //注意这里面的i表示的是第几条边
{
tmp.cost = now.cost + f[i].cost;
tmp.u = f[i].v;
tmp.s = now.s + f[i].l;
Q.push(tmp);
}
}
return -1;
}
int main()
{
while(~scanf("%d%d%d",&K,&N,&R))
{
memset(head,0,sizeof(head));
for(int i = 1; i <= R; i++)
{
scanf("%d%d%d%d",&f[i].u,&f[i].v,&f[i].l,&f[i].cost);
f[i].next = head[f[i].u]; //存储上一次出现的位置
head[f[i].u] = i; //存储这次出现的位置
}
printf("%d\n",bfs());
}
return 0;
}