最小花费最短路
这题和模板题也很像啊,不是很难。已知起点终点,无负权边。跑一遍dijkstra,只不过最后排序的时候多考虑一个费用问题,其实加一个结构体排序就可以了,非常方便,可惜就是不想写结构体排序,好吧详细内容见代码。
题目 :
友情链接
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#pragma GCC optimize(2)
#define INF 0x3f3f3f3f
#define min(a,b) a>b?b:a
struct Node
{
int adj,val;
}g[1005][1005];
int dist[1005];
int value[1005];
int used[1005];
int n,m,i,j;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void Dijkstra(int s){
memset(dist,0x3f,sizeof(dist));
memset(value,0x3f,sizeof(value));
memset(used,0,sizeof(used));
dist[s]=0;
value[s]=0;
while(1){
int k,u=-1,d[1005];
int min=INF;
memset(d,0,sizeof(d));
for(i=1;i<=n;i++){
if(used[i]==0&&dist[i]<min)
{
min=dist[i];
u=i;
}
}
if(u==-1){
return ;
}
for(i=1,k=0;i<=n;i++){
if(dist[u]==dist[i]&&used[i]==0){
d[k++]=i;
}
}
for(i=0;i<k;i++){
used[d[i]]=1;
}
for(i=0;i<k;i++){
for(j=1;j<=n;j++){
if(g[d[i]][j].adj!=INF && (dist[d[i]]+g[d[i]][j].adj)<=dist[j])
{
if((dist[d[i]]+g[d[i]][j].adj)<dist[j])
value[j]=value[d[i]]+g[d[i]][j].val;
else
value[j]=min(value[j],value[d[i]]+g[d[i]][j].val);
dist[j]=dist[d[i]]+g[d[i]][j].adj;
}
}
}
}
}
int main(){
while((n=read(),m=read()) && (n!=0&&m!=0)){
int a,b,d,p;
memset(g,0x3f,sizeof(g));
for(i=1;i<=m;i++){
a=read();
b=read();
d=read();
p=read();
if(d<=g[a][b].adj){
if(d==g[a][b].adj){
g[a][b].val=g[b][a].val=min(p,g[a][b].val);
}
else{
g[a][b].val=g[b][a].val=p;
}
g[a][b].adj=g[b][a].adj=d;
}
}
int s,t;
s=read();
t=read();
Dijkstra(s);
printf("%d %d\n",dist[t],value[t]);
}
return 0;
}
中间一大堆没用的优化请忽略。。。。。。
打卡第二篇博客