牛客小白月赛16 J.小雨坐地铁(最短路/分层图最短路+虚点)

题目

n(n<=500)个地铁站,m(m<=1e3)条地铁线,可能公用地铁站

第i条地铁,进站花费ai价格,每坐一站花费bi价格(1<=ai,bi<=100)

第i条地铁,有ci个地铁站,相邻的两个相连,

多条线经过同一站点可以换乘,换乘时需要花费另一条地铁的入站价格

现从s出发,想要到t,问最少花费的价格,不可达输出-1

思路来源

https://ac.nowcoder.com/discuss/205975?type=101&order=0&pos=1&page=1

https://ac.nowcoder.com/acm/contest/view-submission?submissionId=40835597

题解

牛客小白月赛16 J.小雨坐地铁(最短路/分层图最短路+虚点)_第1张图片

考虑每条地铁线一旦开始坐,就计这条地铁线的价格,所以得分开建图,不然无法记录是从上一站的哪条地铁线转移而来

每条地铁单独建一个图,然后每个地铁的每个点i都和虚点i相连,这样公用i的点就可以通过虚点实现地铁线的连通

进虚点不需要代价,出虚点进入第j条地铁,相当于第j条地铁进站买票花费a[j]代价

最后从s的虚点出发,一出发即相当于买票;到达t的虚点,进入t的虚点不需要代价,所以答案等同

分层图最短路,还是重在建图

代码

#include
using namespace std; 
typedef long long ll;
typedef pair pii;
const ll INF=2e18;
const int N=1e6,M=2e6;
//minn==1e3*500+1e3 1e3条共链地铁1e3虚点 minm=1e3*500*2 1e3条链完全重合 +1e3*500*2 1e3个虚点每个连500个点 
using namespace std;
int n,m,s,t;
int a,b,c,last,v;
int head[N],cnt;
ll dis[N];
bool vis[N];
struct edge{int to,nex;ll w;}e[M];
priority_queue,greater >q;
void init()
{
	cnt=0;
	for(int i=0;idis[pos]+w)
		    {
		    dis[v]=dis[pos]+w;
		    q.push(pii(dis[v],v));
		    }
		}
    }
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	init();
	for(int i=0;i

 

你可能感兴趣的:(最短路)