SDUToj 2622 最短路径(SPFA)

最短路径

Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^

题目描述

为了准备一年一度的校赛,大家都在忙着往赛场搬运东西,比如气球什么的。这时 YY 也没有闲着,他也加入了搬运工的行列。已知学校有 N 个路口和 M 条路, YY 并不是把东西直接搬到赛场,而是从 S 路口搬运到 T 路口。由于 YY 非常懒而且他有轻度强迫症。所以他要走的路需要尽可能的短,并且走路径 X 的倍数。

输入的第一行为一个正整数T(1 20),代表测试数据组数。

输入的第一行为两个正整数NM1 100, 1 10000)。

接下来每M行三个正整数UVW≤U,V<N, 0230),代表有一条从UV的长度为W有向路径

最后一行三个正数≤S,T (0X <=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;
}


你可能感兴趣的:(最短路)