树的应用:最短路(多对节点之间的最短路径)

最短路

  • 题目描述
    • 题目输入与输出
      • 思路及代码

题目描述

暗黑法王JZL的爪牙几乎渗透了整个魔法世界,你所在的学院“兰亭园”成为唯一安全的地方,为了对抗邪恶的暗黑法王,学院的法师们需要不停地修炼自己的法术,而当他们修炼到一定程度时,就可以进阶成下一阶魔法师。比如最开始所有学员都是白袍魔法师,可以进阶成蓝袍法师,黄袍法师、绿袍法师……然而大部分法师在暗黑法王面前都是弟弟,只有红袍法师才能与之抗衡,可惜学院迄今为止没有一个法师能够修炼成红袍法师,时间紧迫,还好学院有祖先们传下来的水晶,这些水晶蕴含着强大的能量,可以让一个法师直接进阶到下一阶法师,非常好用。现在已知学院已有的法师种类和进阶关系,要用最少的水晶产生一个红袍法师,水晶数量有限,魔法协会会长GHX将这个任务交给了优秀的你,你能为他解决这个问题吗?

题目输入与输出

输入
首先第一行输入四个整数N(1 <= N <= 1000),M (1 <= M <= 100000),K(1 <= N - 1),S(1 <= S <= N), 分别表示有N种法师,M种进阶关系,初始拥有的法师种类数量,和红袍法师的编号,第二行输入K个整数ai(1 <= ai <= N),表示K个初始法师的编号,第3行到第M + 2行每行输入三个整数U,V(1 <= U, V <= N),W(1 <= W <= 100000),表示U法师可以花费W个水晶进阶为V法师。某法师进阶到另一法师的途径不一定唯一,也可能存在进阶到原来的法师等级的情况。
输出
一个整数表示产生红袍法师所需要的最少水晶数量,如果无法产生,输出“GG“。(不带引号)
样例输入:

8 10 3 8
3 4 5
2 1 2
1 3 1
3 2 6
3 5 8
3 4 2
4 7 3
5 7 5
4 6 4
6 8 2
7 8 4

样例输出:

6

思路及代码

题目分析:首先找最少代价,也就是两个点之间的距离之和,或者两个点之间的最短距离,又是多对点之间的最短距离,所以是用Flod算法,时间复杂度是n的三次方
代码:

#include
#include
#include
using namespace std;
typedef long long int ll;
const ll MAX=1010;
const ll MAX_V=100010;
const ll INF=1000000;
ll n,m,k,s;
typedef struct
{
    ll e[MAX][MAX];
    ll u,v;
}MATHGRAPH;
MATHGRAPH g;//邻接表
ll a[MAX];//记录数据
ll dist[MAX];//题目找的数组
ll A[MAX][MAX];//最后的最短路径图
void fold()
{
    for(ll i=1;i<=g.u;i++)
    {
        for(ll j=1;j<=g.u;j++)
        {
            A[i][j]=g.e[i][j];
        }
    }
    for(ll k=1;k<=g.u;k++)//对每个点都要试一遍
    {
        for(ll i=1;i<=g.u;i++)
        {
            for(ll j=1;j<=g.u;j++)
            {
                if(A[i][j]>A[i][k]+A[k][j])//更新
                {
                    A[i][j]=A[i][k]+A[k][j];
                }
            }
        }
    }
    ll j=0;
    for(ll i=0;i<k;i++)
    {
        ll t=a[i];
        dist[j++]=A[t][s];
    }
    sort(dist,dist+j);//排序
    if(dist[0]==INF)cout<<"GG"<<endl;
    else cout<<dist[0]<<endl;
 
}
int main()
{
    cin>>n>>m>>k>>s;
    for(ll i=0;i<k;i++)
    {
        cin>>a[i];
    }
    for(ll i=0;i<=n;i++)
    {
        for(ll j=0;j<=n;j++)
        {
            g.e[i][j]=INF;
            if(i==j)g.e[i][j]=0;//对自环的处理
        }
    }//初始化
    for(ll i=0;i<m;i++)
    {
        ll u,v,w;
        cin>>u>>v>>w;
        w=min(g.e[u][v],w);
        g.e[u][v]=w;
    }
    g.u=n,g.v=m;//初始化
    fold();
    return 0;
 
}

你可能感兴趣的:(数据结构,算法,数据结构)