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

因为有中转站,所以不清楚从哪里来,状态不好记录(貌似可以开dis[i][j],表示在i号线到j点的最短路)
所以对于每一个点建立一个虚点,然后对于每一条地铁上的点都连上这个虚点,达到中转的目的。

code

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 5e5+1005;
#define IOS ios::sync_with_stdio(0)
#define ull unsigned ll
#define uint unsigned
#define pai pair<int,int>
#define pal pair<ll,ll>
#define IT iterator
#define pb push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);++i)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);--i)
#define endl '\n'
#define ll long long
const ll mod = 1e9+7;

struct node{
	int u;
	ll dis;
	bool operator < (const node &b)const {
		return dis > b.dis;
	}
};
vector<node>sp[man];
bool vis[man];
ll dis[man];
priority_queue<node>q;
void dij(int s){
	memset(vis,0,sizeof(vis));
	memset(dis,0x3f,sizeof(dis));
	dis[s] = 0;
	q.push(node{s,dis[s]});
	while(q.size()){
		node tp = q.top();
		q.pop();
		if(vis[tp.u])continue;
		vis[tp.u] = 1;
		for(auto u:sp[tp.u]){
			if(vis[u.u])continue;
			if(dis[u.u]>dis[tp.u]+u.dis){
				dis[u.u] = dis[tp.u] + u.dis;
				q.push(node{u.u,dis[u.u]});
			}
		}
	}
}

signed main() {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
    int n,m,s,t;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i = 0;i < m;++i){
        int a,b,c;scanf("%d%d%d",&a,&b,&c);
        int u = 0,v;
        while(c--){
            scanf("%d",&v);
            if(u){
                sp[i*n+v].push_back(node{i*n+u,b});
                sp[i*n+u].push_back(node{i*n+v,b});
            }
            sp[m*n+v].push_back(node{i*n+v,a});
            sp[i*n+v].push_back(node{v+n*m,0});
            u = v;
        }
    }
    dij(s+m*n);
    printf("%lld\n",dis[t+n*m]==0x3f3f3f3f3f3f3f3f?-1:dis[t+n*m]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43571920/article/details/107289357
今日推荐