最短路径
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;
}