最短路径
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
为了准备一年一度的校赛,大家都在忙着往赛场搬运东西,比如气球什么的。这时
YY
也没有闲着,他也加入了搬运工的行列。已知学校有
N
个路口和
M
条路,
YY
并不是把东西直接搬到赛场,而是从
S
路口搬运到
T
路口。由于
YY
非常懒而且他有轻度强迫症。所以他要走的路需要尽可能的短,并且走过路径的数目要为
X
的倍数。
输入的第一行为一个正整数T(1≤ 20),代表测试数据组数。
输入的第一行为两个正整数N和M(1≤ 100, 1≤ 10000)。
接下来每M行三个正整数UVW≤U,V<N, 0≤230),代表有一条从U到V的长度为W的有向路径。
最后一行三个正数≤S,T (0≤X <=10)。
示例输入
2 2 1 0 1 1 0 1 2 3 2 0 1 1 1 2 1 0 2 2
示例输出
No Answer! 2
//此题与其他题目不同之处在于,要求走的步数为x的整数倍,显然要用个东西将其记录下来,那么就用到了 二维SPFA。
#include<climits>//调用STL中的LONG_LONG_MAX 必有climts头文件 #include<cstring> #include<cstdio> #include<iostream> #include<queue> #include<vector> //使用了vector #include<math.h> #include<stack> using namespace std; int n,m,a,b,x; struct node { int a; long long w;//权值及dis数组用long long 开 }; long long dis[1100][20]; int vis[1100],z,s,e; long long c; struct node tmp; vector<struct node>mp[1100];//vector 用法和queue类似 void SPFA() { int i,j,k; queue<int >q; for(i=0;i<=n;i++) { for(j=0;j<=x;j++) { dis[i][j]=LONG_LONG_MAX; } } dis[s][0]=0; memset(vis,0,sizeof(vis)); vis[s]=1; q.push(s); while(!q.empty()) { k=q.front(); q.pop(); vis[k]=0;//弹出后直接清标记 z=mp[k].size(); for(i=0;i<z;i++) { int p=mp[k][i].a;//p是 当前点与相连点的距离 for(j=0;j<x;j++) { if(dis[k][j]<LONG_LONG_MAX&&dis[ p][ (j+1)%x ]>dis[ k ][j]+mp[ k ][i].w )//dis[k][j]要小于LONG_LONG_MAX。 { dis[p][ (j+1)%x]=dis[k][j]+mp[k][i].w; if(!vis[p]) { q.push(p); vis[p]=1; } } } } } } int main() { int t,i,j; cin>>t; while(t--) { cin>>n>>m; for(i=0;i<=n;i++)//vector一定要有mp的清理! mp[i].clear(); for(i=0;i<m;i++) { cin>>a>>b>>c; tmp.a=b;//题目中提到的又向路径将要抵达的点赋给tmp.a tmp.w=c; mp[a].push_back(tmp);//然后将tmp压到mp[a].push_back()下; } cin>>s>>e>>x; SPFA(); if(dis[e][0]>=LONG_LONG_MAX)//必用climits { cout<<"No Answer!"<<endl; } else cout<<dis[e][0]<<endl; } return 0; }