1 条题解

  • 0
    @ 2025-4-22 12:35:51

    🔍 解题思路

    图论,单源最短路,bellman_ford队列优化算法,需要稍微处理一点,在松弛之前算出需要等多长时间,之后松弛,另外需要注意,可能会出现两个路口灯的持续时间都相同,但颜色相反,这种情况下这条路永远没法走,因而当算得等待时间加上途经用时已经无法松弛时,就不用再算了,剩下的部分,就是最短路了 从实现层面上,主要还是处理等待时间,将到达路口的时间加上最初的剩余时间,对灯循环一次的周期求模,由此判断当前灯的状态,若要等待,则等待两个路口最先变灯的时间,然后再计算判断 本题用的静态邻接表

    #include<iostream>
    using namespace std;
    const int N=360,M=14400;
    #define int long long
    //这里也许没必要
    //不过还是以防万一比较好
    long long INF=0x3fffffffffffffffll;
    int gr[N][N];
    int dis[N];
    bool used[N];
    char col[N];
    int t[2][N],r[N];
    int s,e;
    int n,m;
    
    int getdelay(int a,int b,int ti){
    	bool st1,st2;
    	int r1,r2;
    	int m1=(t[0][a]+t[1][a]),m2=(t[0][b]+t[1][b]);
    	
    	if(ti%m1<r[a]){
    		st1=col[a];
    		r1=r[a]-ti%m1+m1;
    	}else if(ti%m1>=(r[a]+t[!col[a]][a])){
    		st1=col[a];
    		r1=r[a]-ti%m1+m1;
    	}else{
    		st1=!col[a];
    		r1=r[a]-ti%m1+t[!col[a]][a];
    	}
    	r1%=m1;
    	if(r1<0)r1+=m1;
    	
    	if(ti%m2<r[b]){
    		st2=col[b];
    		r2=r[b]-ti%m2;
    	}else if(ti%m2>=(r[b]+t[!col[b]][b])){
    		st2=col[b];
    		r2=r[b]-ti%m2+m2;
    	}else{
    		st2=!col[b];
    		r2=r[b]-ti%m2+t[!col[b]][b];
    	}
    	r2%=m2;
    	if(r2<0)r2+=m2;
    	
    	if(r1==0){
    		st1=!st1;
    		r1=t[st1][a];
    	}
    	
    	if(r2==0){
    		st2=!st2;
    		r2=t[st2][b];
    	}
    	
    	
    	if(st1==st2){
    		return 0;
    	}else if(r1!=r2){
    		return min(r1,r2);
    	}else if(t[!st1][a]!=t[!st2][b]){
    		return r1+min(t[!st1][a],t[!st2][b]);
    	}else if(m1!=m2){
    		return r1+t[!st1][a]+min(t[st1][a],t[st2][b]);
    	}else{
    		return -1;
    	}
    }
    
    int a,b,w;
    #undef int
    int main(){
    #define int long long
    	ios::sync_with_stdio(false);
    	cin>>s>>e;
    	cin>>n>>m;
    	for(int i=1;i<=n;i++){
    		cin>>col[i];
    		if(col[i]=='B')col[i]=0;
            //直接把颜色变为0/1便于操作
    		else col[i]=1;
    		cin>>r[i]>>t[0][i]>>t[1][i];
    		dis[i]=INF;
    		for(int j=1;j<=n;j++)gr[i][j]=INF;
    	}
    	while(m--){
    		cin>>a>>b>>w;
    		gr[a][b]=gr[b][a]=min(gr[a][b],w);
    	}
    	dis[s]=0;
    	for(int k=1;k<=n;k++){
    		int id=0,mindis=INF,del;
    		for(int i=1;i<=n;i++){
    			if(!used[i]&&dis[i]<mindis){
    				id=i;
    				mindis=dis[i];
    			}
    		}
    		if(id==0)break;
    		used[id]=1;
    		for(int i=1;i<=n;i++){
    			if(used[i])continue;
    			del=getdelay(id,i,mindis);
    			if(del==-1)continue;
    			dis[i]=min(dis[i],mindis+del+gr[id][i]);
    		}
    	}
    	if(dis[e]==INF)cout<<"0";
        //注意这里是0而不是-1
    	else cout<<dis[e];
    }
    • 1

    信息

    ID
    159
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者