2020杭电多校第四场1004

题意:给你n个城市和m条边,并将这n个城市分为三类—L,R,M,其中在L类的城市必须用左手;在R类的城市必须用右手;在M类的城市不限制左右手。换一次手需要x的时间。问从起点到终点的最短路径。
思路:拆点的思想,将每个城市划分为L,R两类点,若边的两个端点类型一个为L,一个为R,需在原边权基础上加x,若为同类型则不需要加x。另外,再设一个源点和汇点,将源点和起点相连,边权为0.将汇点和终点相连,边权为0。连线规则:城市为M,则需要连它的L和R。而对于L,R只需要连对应的类型即可。连完跑一下最短路就可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+5;
const ll inf=99999999999999999;
struct Edge{
    
    
	ll to,w,prev;
}edge[N*8];
ll T,n,m,s,t,x,cnt,head[N*4],v[N*4],dis[N*4];
string k;
inline void add(ll xx,ll yy,ll ww){
    
    
	edge[++cnt].to=yy;edge[cnt].w=ww;
	edge[cnt].prev=head[xx];head[xx]=cnt;
	edge[++cnt].to=xx;edge[cnt].w=ww;
	edge[cnt].prev=head[yy];head[yy]=cnt;
} 
inline void dijkstra(){
    
    
	priority_queue<pair<ll,ll> > q;
	dis[0]=0;q.push({
    
    0,0});
	while(!q.empty()){
    
    
		ll xx=q.top().second;q.pop();
		if(v[xx]) continue;
		v[xx]=1;
		for(ll i=head[xx];i;i=edge[i].prev){
    
    
			ll to=edge[i].to;
			if(dis[to]>dis[xx]+edge[i].w){
    
    
				dis[to]=dis[xx]+edge[i].w;
				q.push({
    
    -dis[to],to});
			}
		}
	}
	cout<<dis[2*n+1]<<endl;
}
int main(){
    
    
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>T;
	while(T--){
    
    
		cin>>n>>m>>s>>t>>x>>k;
		for(ll i=0;i<=2*n+1;i++) dis[i]=inf,v[i]=head[i]=0;
		ll u,v,w;cnt=0;
		if(k[s-1]=='L') add(0,s,0);
		else if(k[s-1]=='R') add(0,s+n,0);
		else add(0,s,0),add(0,s+n,0);
		if(k[t-1]=='L') add(t,2*n+1,0);
		else if(k[t-1]=='R') add(t+n,2*n+1,0);
		else add(t,2*n+1,0),add(t+n,2*n+1,0);
		for(ll i=1;i<=m;i++){
    
    
			cin>>u>>v>>w;
			if(k[u-1]=='L'&&k[v-1]=='R') add(u,v+n,w+x);
			else if(k[u-1]=='R'&&k[v-1]=='L') add(u+n,v,w+x);
			else if(k[u-1]=='L'&&k[v-1]=='M') add(u,v,w),add(u,v+n,w+x);
			else if(k[u-1]=='M'&&k[v-1]=='L') add(u,v,w),add(u+n,v,w+x);
			else if(k[u-1]=='R'&&k[v-1]=='M') add(u+n,v,w+x),add(u+n,v+n,w);
			else if(k[u-1]=='M'&&k[v-1]=='R') add(u,v+n,w+x),add(u+n,v+n,w);
			else if(k[u-1]=='L'&&k[v-1]=='L') add(u,v,w);
			else if(k[u-1]=='R'&&k[v-1]=='R') add(u+n,v+n,w);
			else add(u,v,w),add(u,v+n,w+x),add(u+n,v,w+x),add(u+n,v+n,w);
 		}
		dijkstra();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43916777/article/details/107747106
今日推荐