CSU - 1808 (最短路)

题意:给你n个点,m条边,边类型不同转移需要额外花费,问1到n的最短路。

思路:因为每个点可能有多种不同类型的边转移过来。因为类型太多我们无法二维记录当前点由那个边转移来的。所以我们可以枚举边。把每条边当成一个点,做最短路。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
	int u,v,t,c,nex;
}e[200005];
int head[100005];
int num=0;
int vis[100005];
ll d[100005];
void add(int u,int v,int c,int t)
{
	e[num].u=u;e[num].v=v;e[num].t=t;e[num].c=c;e[num].nex=head[u];head[u]=num++;
}

int n,m;
ll dji()
{
	ll ans=1000000000000000000;
	priority_queue< pair<ll,int> > q;
	memset(vis,0,sizeof(vis));
	for(int i=0;i<num;i++)
	{
		d[i]=1000000000000000000;
	}
	for(int i=head[1];~i;i=e[i].nex)
	{
		d[i]=e[i].t;
		q.push(make_pair(-d[i],i));
	}
	while(!q.empty())
	{
		pair<ll,int> tmp=q.top(); q.pop();
		vis[tmp.second]=1;
		if(e[tmp.second].v==n) ans=min(ans,d[tmp.second]);
		for(int i=head[e[tmp.second].v];~i;i=e[i].nex)
		{
			int v=e[i].v;
			if(!vis[v]&&d[i]>d[tmp.second]+e[i].t+abs(e[tmp.second].c-e[i].c))
			{
				d[i]=d[tmp.second]+e[i].t+abs(e[tmp.second].c-e[i].c);
				q.push(make_pair(-d[i],i));
			}
		}
	}
	return ans;
}

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(head,-1,sizeof(head));
		num=0;
		for(int i=0;i<m;i++)
		{
			int u,v,c,t;scanf("%d%d%d%d",&u,&v,&c,&t);
			add(u,v,c,t);
			add(v,u,c,t);
		}
		printf("%lld\n",dji());
	}
	return 0;
}
发布了155 篇原创文章 · 获赞 32 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_37632935/article/details/89553260
今日推荐