杭电多校2020第四场

Deliver the Cake

题意:

n个地点,m条双向道路,地点的类型分L、R、M三种,到达L点需保持状态L,到达R需保持状态R,到M两种状态都可以,切换状态需要消耗时间x,问s到t点所需最少时间。

题解:

将M类型的点一分为二,1 ~ N所有类型为M的点设为L点,N+1 ~ 2N所有类型为M的点设为R点,那么在加边的时候有7种情况:

(1) u 为 L 并且 v 为 R 或者 u 为 R 并且 v 为 L,那么 u 到 v 的距离为 w + x。
(2) u 为 L 并且 v 为 L 或者 u 为 R 并且 v 为 R,那么 u 到 v 的距离为 w。
(3) u 为 L 并且 v 为 M,那么 u 到 v 的距离为 w,u 到 v + n 的距离为 w + x。
(4) u 为 R 并且 v 为 M,那么 u 到 v 的距离为 w + x,u 到 v + n 的距离为 w。
(5) u 为 M 并且 v 为 L,那么 u 到 v 的距离为 w,u + n 到 v 的距离为 w + x。
(6) u 为 M 并且 v 为 R,那么 u 到 v 的距离为 w + x,u + n 到 v 的距离为 w。
(7) u,v 同时为 M,那么 u 到 v 的距离为 w,u + n 到 v + n 的距离为w,u + n 到 v 的距离为 w + x,u 到 v + n 的距离为w + x。

如果起点为M,只需添加一条权值为0,从s到s+n的边即可。

AC_CODE:

const int maxn = 2e5+5;
const int M = 2e6+5;
ll n,m,s,t,x,cnt;
char tt[maxn];
struct node{
	int to;
	int next;
	ll w;
	bool operator<(const node&a) const{
		return a.w < w;
	}
}edge[M],Now,Next;
int head[maxn];

void init(){
	FOR(i,0,maxn-2) head[i] = -1;
	cnt = 0;
}

void add(int u, int v, ll w){
	edge[++cnt].to = v;
	edge[cnt].next = head[u];
	edge[cnt].w = w;
	head[u] = cnt; 
}

bool vis[maxn];
ll dis[maxn];

void dijkstra(){
	FOR(i,0,maxn) vis[i] = 0;
	FOR(i,0,maxn) dis[i] = 1LL<<61LL;
	Now.to = s;
	dis[s] = 0;
	priority_queue<node>pq;
	pq.push(Now);
	while(!pq.empty()){
		Now = pq.top();
		pq.pop();
		int now = Now.to;
		if(vis[now]) continue;
		vis[now] = 1;
		for(int i=head[now]; i!=-1; i=edge[i].next){
			int u = edge[i].to;
			if(!vis[u] && dis[u] > dis[now] + edge[i].w){
				dis[u] = dis[now] + edge[i].w;
				Next.to = u;
				Next.w = dis[u];
				pq.push(Next);
			}
		}
	}
	W(min(dis[t],dis[t+n]));
}



void solve(){
	init();
	R(n,m,s,t,x);
	scanf("%s",tt+1);
	if(tt[s] == 'M') add(s,s+n,0),add(s+n,s,0);
	while(m--) {
		ll u,v,w;
		R(u,v,w);
		if((tt[u] == 'L' && tt[v] == 'R') || (tt[u] == 'R' && tt[v] == 'L')) {
			add(u,v,w+x); add(v,u,w+x);
		} else if((tt[u] == 'L' && tt[v] == 'L') || (tt[u] == 'R' && tt[v] == 'R')) {
			add(u,v,w); add(v,u,w);
		} else if(tt[u] == 'L' && tt[v] == 'M') {
			add(u,v,w); add(v,u,w);
			add(u,v+n,w+x); add(v+n,u,w+x);
		} else if(tt[u] == 'R' && tt[v] == 'M') {
			add(u,v,w+x); add(v,u,w+x);
			add(u,v+n,w); add(v+n,u,w);
		} else if(tt[u] == 'M' && tt[v] == 'L') {
			add(u,v,w); add(v,u,w);
			add(u+n,v,w+x); add(v,u+n,w+x);
		} else if(tt[u] == 'M' && tt[v] == 'R') {
			add(u,v,w+x); add(v,u,w+x);
			add(u+n,v,w); add(v,u+n,w);
		} else {
			add(u,v,w); add(v,u,w);
			add(u+n,v,w+x); add(v,u+n,w+x);
			add(u,v+n,w+x); add(v+n,u,w+x);
			add(u+n,v+n,w); add(v+n,u+n,w);
		}
	}
	dijkstra();
}

你可能感兴趣的:(杭电多校2020第四场)