路数有限制(w的倍数)的最短路,【二维dijkstra】

比一般的dijkstra数组多了一维。

#include<iostream>  
#include<algorithm>  
#include<map>//ll dx[4]={0,0,-1,1};ll dy[4]={-1,1,0,0};  
#include<set>//  
#include<vector>  
#include<cmath>  
#include<stack>  
#include<string.h>  
#include<stdlib.h>  
#include<cstdio>   
#include<string>  
#define mod 1000000007
#define ll long long
#define inf 10000000000000
#define lowbit(x) (x) & (-x) 
using namespace std;
ll x[102][102];
ll d[102][12];   //记录i点在路数%w=j时的最短路程
int v[102][12];   //判断i点有没有出现过路数%w=j的状态
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;++i){
			for(int j=0;j<n;++j){
				x[i][j]=inf;
			}
		}
		while(m--){
			int a,b;
			ll c;
			scanf("%d%d%lld",&a,&b,&c);
			x[a][b]=min(x[a][b],c);
		}
		int st,ed,w;
		scanf("%d%d%d",&st,&ed,&w);
		for(int i=0;i<n;++i){
			for(int j=0;j<w;++j){
				d[i][j]=inf;
				v[i][j]=0;
			}
		}
		d[st][0]=0;
		while(1){ //本来这里是for(int i=0;i<n;++i)
			ll get=inf;
			ll idx=-1,num=-1;
			for(int i=0;i<n;++i){
				for(int j=0;j<w;++j){
					if(v[i][j]==0&&d[i][j]<get){
						get=d[i][j];
						idx=i;
						num=j;
					}
				}
			}
			if(idx==-1||(idx==ed&&num==0)) //当前已经无法拓新或者已经找到了终点是w倍数的情况,直接退出
				break;
			v[idx][num]=1;
			for(int i=0;i<n;++i){
				if(x[idx][i]==inf||v[i][(num+1)%w]==1) continue;
				d[i][(num+1)%w]=min(d[i][(num+1)%w],d[idx][num]+x[idx][i]);
			}
		}
		if(d[ed][0]==inf)
			printf("No Answer!\n");
		else
			printf("%lld\n",d[ed][0]);
	}
	return 0;
}


你可能感兴趣的:(路数有限制(w的倍数)的最短路,【二维dijkstra】)