域名访问网站 过程,网站 免费 托管运营,网站优化推广外包,wordpress 萌主题下载This way
题意#xff1a; 给你一个有向图#xff0c;1号点为起点#xff0c;n为终点。你可以在k的倍数的时间点在起点开始#xff0c;每条边的边长为1#xff0c;同时#xff0c;每条边有一个限定时间ai#xff0c;表示你必须在大于等于ai的时间点才能走这条边。 …This way
题意 给你一个有向图1号点为起点n为终点。你可以在k的倍数的时间点在起点开始每条边的边长为1同时每条边有一个限定时间ai表示你必须在大于等于ai的时间点才能走这条边。 你需要在k的倍数的时间点到终点问你在终点的最早时间如果不存在输出-1.
题解 应当是一条最短路在思考每条边的限定时间的时候会发现假设这条边从a到b边权为c。那么如果在d(dc)的时刻到达a时通不过所以我们要么延迟k的倍数次从起点开始使得到达a的时候是dnk时刻,并且满足dnka且最小要么就是绕个路再回到a点。 于是我们发现这两种情况第一种可以快速处理不需要重新走一遍直接假设已经是晚了nk的时间到达即可。 第二种情况假设再次到达a的时刻为e满足ea那么对于这种情况又细分为两种 1.k|(e-d)也就是dnke。这个就如同上一种情况一般假设晚到即可。 2.e!dnk那么我思考至此发现其实到达a的时候总共只有k种情况也就是到达a位置的步长%k的不同情况。对于每一种情况存下来最短路长即可。 所以设置dis[i][j]表示到达i位置走过的路长%kj时最短路程。知道了这个以后直接d。
#includebits/stdc.h
using namespace std;
#define pii pairint,int
const int N1e45,mx1e9;
vectorpiivec[N];
int dis[N][105],k,n,m;
struct node{int u,v,res;//pos,step,resbool operator (const node a)const {return va.v;}
};
priority_queuenodeQ;
int dij(){Q.push({1,0,0});dis[1][0]0;while(!Q.empty()){node uQ.top();Q.pop();if(u.vdis[u.u][u.res])continue;for(pii ne:vec[u.u]){int nv;if(ne.secondu.v)nvu.v1(ne.second-u.vk-1)/k*k;else nvu.v1;int nrnv%k;if(dis[ne.first][nr]nv)dis[ne.first][nr]nv,Q.push({ne.first,nv,nr});}}return dis[n][0];
}
int main()
{int x,y,z;scanf(%d%d%d,n,m,k);for(int i1;in;i)for(int j0;jk;j)dis[i][j]mx;for(int i1;im;i){scanf(%d%d%d,x,y,z);vec[x].push_back({y,z});}int ansdij();if(ansmx)printf(-1\n);else printf(%d\n,ans);return 0;
}