繁繁的游戏

题目描述

					繁繁想和小伙伴们打游戏,游戏在一个山庄进行,这个山庄有N座山,编号为1到N,为了方便大家在不同的山之间移动,繁繁建了一些桥,由于技术的原因,桥连接的两座山的高度差不能超过d,现在已知这些桥,求这个山庄最高的山和最低的山差距最大是多少?数据保证所有山之间都是联通的。						

输入

					第一个一个数T,表示测试数据数量(T<=5,2<=N<=50,0<=d<=1000) 

每组数据第一行两个数N和d
接下来一个N行N列的矩阵,第i行j列为Y表示i和j之间建了一座桥,否则表示没有建保证第i行j列和第j行i列值相同,并且第i行第i列值为N

输出

					T行,每行一个答案,若最大值可能为正无穷,输出-1						

样例输入

3 
3 10 
NYN 
YNY 
NYN 
2 1 
NN 
NN 
6 1000 
NNYNNN 
NNYNNN 
YYNYNN 
NNYNYY 
NNNYNN 
NNNYNN

样例输出

20 
-1 
3000

提示

第一个样例,1和2之间不能超过d,2和3之间不能超过d,那么最大就是1和2差恰好为d,2和3差恰好为d

对于20%的数据,T<=3,N<=40
对于50%的数据,T<=3
对于100%的数据,T<=5,2<=N<=50,0<=d<=1000

代码

//#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<climits>
#include<queue>
#include<set>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define swap(x,y) (x^=y,y^=x,x^=y)
typedef long long ll;
using namespace std;
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1;
    char c=getchar();
    for(; c<'0'||c>'9'; c=getchar()) if(c=='-') f=-1;
    for(; c>='0'&&c<='9'; c=getchar()) x=(x<<1)+(x<<3)+(c&15);
}
template<typename T>inline void print(T x)
{
    if(x<0) putchar('-'),x*=-1;
    if(x>=10) print(x/10);
    putchar(x%10+'0');
}
const int N=55;
const int INF=0x3f3f3f3f;
int num[N][N];
int n,d;
int main()
{
    int t;
    read(t);
    char ch;
    while(t--)
    {
        memset(num,0x3f,sizeof(num));
        read(n);
        read(d);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                cin>>ch;
                if(ch=='Y')
                    num[i][j]=num[j][i]=1;
            }
        for(int k=1; k<=n; k++)
            for(int i=1; i<=n; i++)
                for(int j=1; j<=n; j++)
                {
                    num[i][j]=min(num[i][j],num[i][k]+num[k][j]);
                }
        int ans=0;
        for(int i=1; i<=n; i++)
            for(int j=i+1; j<=n; j++)
                ans=max(ans,num[i][j]);
        if(ans==INF)
            cout<<-1<<endl;
        else
        {
            print(ans*d);
            puts("");
        }
    }
    return 0;
}

思路

所以最短路的最大值。

PS

最短路是基于dp思想的,注意模板,以下这种dp不可取。

贴一个错误的代码

//#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<climits>
#include<queue>
#include<set>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define swap(x,y) (x^=y,y^=x,x^=y)
typedef long long ll;
using namespace std;
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1;
    char c=getchar();
    for(; c<'0'||c>'9'; c=getchar()) if(c=='-') f=-1;
    for(; c>='0'&&c<='9'; c=getchar()) x=(x<<1)+(x<<3)+(c&15);
}
template<typename T>inline void print(T x)
{
    if(x<0) putchar('-'),x*=-1;
    if(x>=10) print(x/10);
    putchar(x%10+'0');
}
const int N=55;
int num[N][N];
int n,d;
ll dp[N];
int main()
{
    int t;
    read(t);
    while(t--){
    memset(dp,0,sizeof(dp));
    memset(num,0,sizeof(num));
    char ch;
    read(n);
    read(d);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
    {
        cin>>ch;
        if(ch=='Y')
        {
            num[i][j]=num[j][i]=1;
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<i;j++)
    {
        if(i!=j&&num[i][j])
        {
            dp[i]=max(dp[i],dp[j]+d);
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
        ans=max(ans,dp[i]);
    if(ans==0)
        cout<<-1<<endl;
    else
    cout<<ans<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xxffxx/p/11795867.html