【216】【较水】最小花费最短路

最小花费最短路

这题和模板题也很像啊,不是很难。已知起点终点,无负权边。跑一遍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;
}


中间一大堆没用的优化请忽略。。。。。。
打卡第二篇博客

猜你喜欢

转载自blog.csdn.net/sericon/article/details/94414640