(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
原题目描述及样例在最下面。
题目大意就是n个点,m条无向边。每条边有一个权值(<=1e9)和一个标号(<=n)。求从1到n的最短路径。
题目还有一个特殊要求,就是从一个点经过2条标号不同的边时,需额外花费边的标号差。
又是一道边最短路,读完题发现和BZOJ4289类似。恶心的边最短路问题。
思路与bzoj4289类似,把边当作点,跑最短路。之前按照那题的方法建图跑最短路,样例啥的都过了,但是蜜汁wa。就从网上学到了另一种方法。
边最短路:
dis[i]
表示从起点 1 到编号为 i 的这条边所指向点的最短路径
维护ans=min(dis[x])
,边x所指向的点为n
1.首先用链式前向星建好无向图。
2.然后遍历起点1 连出去的边。初始化dis[i] = cw[i].w
( i 是边的编号),并加入队列。
3.然后跑优先队列优化的dijkstra就行了。
(不知道为什么在push的时候加vis标记就不对,如果有那位大佬是在push处加vis标记过的,求教)
#include
#include
#include
#include
#include
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pairint> pii;
const int N = 2e5+5;
const LL INF=0x3f3f3f3f3f3f3f3f;
int n,m,tot;
int vis[N],head[N];
LL dis[N];
struct lp{
int u,v,id,nex;
LL w;
}cw[N];
inline int ab(int x){
return x<0?-x:x;
}
void dij(){
priority_queuevector,greater >Q;
for(int i=0,a,b,c,d;iscanf("%d%d%d%d",&a,&b,&c,&d);
cw[++tot].u=a;cw[tot].v=b;cw[tot].w=d*1LL;cw[tot].id=c;cw[tot].nex=head[a];head[a]=tot;
cw[++tot].u=b;cw[tot].v=a;cw[tot].w=d*1LL;cw[tot].id=c;cw[tot].nex=head[b];head[b]=tot;
}
for(int i=head[1];~i;i=cw[i].nex){
dis[i]=cw[i].w;
Q.push(make_pair(dis[i],i));
}
LL ans=INF;
while(!Q.empty()){
pii now=Q.top();Q.pop();
if(vis[now.se])continue;
vis[now.se]=1;
int a=cw[now.se].v,u=now.se;
if(a==n){
ans=min(ans,dis[u]);
}
for(int i=head[a];~i;i=cw[i].nex){
if(vis[i])continue;
if(dis[i]>dis[u]+ab(cw[i].id-cw[u].id)+cw[i].w){
dis[i]=dis[u]+ab(cw[i].id-cw[u].id)+cw[i].w;
Q.push(make_pair(dis[i],i));
}
}
}
printf("%lld\n",ans );
}
inline void init(){
tot=-1;
memset(head,-1,sizeof(head));
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
}
int main(int argc, char const *argv[]){
while(~scanf("%d%d",&n,&m)){
init();
dij();
}
return 0;
}
Description
Bobo 居住在大城市 ICPCCamp。
ICPCCamp 有 n 个地铁站,用 1,2,…,n 编号。 m 段双向的地铁线路连接 n 个地铁站,其中第 i 段地铁属于 ci 号线,位于站 ai,bi 之间,往返均需要花费 ti 分钟(即从 ai 到 bi 需要 ti 分钟,从 bi 到 ai 也需要 ti 分钟)。
众所周知,换乘线路很麻烦。如果乘坐第 i 段地铁来到地铁站 s,又乘坐第 j 段地铁离开地铁站 s,那么需要额外花费 |ci-cj | 分钟。注意,换乘只能在地铁站内进行。
Bobo 想知道从地铁站 1 到地铁站 n 所需要花费的最小时间。
Input
输入包含不超过 20 组数据。
每组数据的第一行包含两个整数 n,m (2≤n≤105,1≤m≤105).
接下来 m 行的第 i 行包含四个整数 ai,bi,ci,ti (1≤ai,bi,ci≤n,1≤ti≤109).
保证存在从地铁站 1 到 n 的地铁线路(不一定直达)。
Output
对于每组数据,输出一个整数表示要求的值。
Sample Input
3 3
1 2 1 1
2 3 2 1
1 3 1 1
3 3
1 2 1 1
2 3 2 1
1 3 1 10
3 2
1 2 1 1
2 3 1 1
Sample Output
1
3
2
Hint
Source
湖南省第十二届大学生计算机程序设计竞赛