1030. Travel Plan_dijkstra算法升级

http://pat.zju.edu.cn/contests/pat-a-practise/1030

输出两个城市间的最短路径值,路径经过的结点

使用dikstra算法,邻接表保存图,使用栈输出保存的路径

理解edge[i]   结点i的邻接链表,保存与i相邻接的边,边结构体保存next,cost,distance

理解路径:每当有更短路径经过newP到t,则path[t]=newP,所以0(s)----2----3(end)

                  由path[3]=2,   再path[2]=0,,     path[0]=-1(初始化作为结束)

                  所以用栈保存,栈顶便是起始点,栈底便是结束点

   

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

struct E
{
	int next;
	int distance;
	int cost;
};
vector<E> edge[510];
stack<int> ans;
int dis[510];                    //到i的最短距离
int costSum[510];                //到i的最小耗费 
bool mark[510];
int path[510];                  //保存路径

void dij(int s,int e,int n)
{
   int i,j;
   dis[s]=0;
   mark[s]=true;
   int newP=s;
   for (i=0;i<n-1;i++)
   {
	   for (j=0;j<edge[newP].size();j++)         //遍历newP的所有邻接点
	   {
		   int t=edge[newP][j].next;        //得到所有边结构体数据 
		   int di=edge[newP][j].distance;
	       int co=edge[newP][j].cost;
		   if (mark[t])
		   {
			   continue;
		   }
		   if (dis[t]==-1 || dis[t]>dis[newP]+di )     //更短距离
		   {
			   dis[t]=dis[newP]+di;
			   costSum[t]=costSum[newP]+co;
			   path[t]=newP;                     //记录经newP到t

		   }
		   if ( dis[t]==dis[newP]+di && costSum[t]>costSum[newP]+co )
		   {
			   costSum[t]=costSum[newP]+co;
			   path[t]=newP;
		   }
	   }
	   int min=123123;
	   for (j=0;j<n;j++)                     //找出现在最小边(未访问结点的)
	   {
		   if (mark[j])
		   {
			   continue;
		   }
		   if (dis[j]==-1)
		   {
			   continue;
		   }
		   if (dis[j]<min)
		   {
			   min=dis[j];
			   newP=j;
		   }
	   }
	   mark[newP]=true;
   }
}

int main()
{
	freopen("D:\\test.txt","r",stdin);
	int n,m,s,e,i;
	cin>>n>>m>>s>>e;
	for (i=0;i<m;i++)
	{
		int a,b,c,d;
		cin>>a>>b>>d>>c;
		E tmp;
		tmp.cost=c;
		tmp.distance=d;
		tmp.next=b;
		edge[a].push_back(tmp);
		tmp.next=a;
		edge[b].push_back(tmp);
	}
	for (i=0;i<n;i++)
	{
		dis[i]=-1;
		mark[i]=false;
		path[i]=-1;
	}
    dij(s,e,n);
	int x=e;
	while (x!=-1)            //路径上经过的点入栈
	{
		ans.push(x);
		x=path[x];
	}
	while (!ans.empty())       //输出:从起始到结束
	{
		cout<<ans.top()<<" ";
		ans.pop();
	}
	cout<<dis[e]<<" "<<costSum[e]<<endl;
	return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值