题意:给你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;
}