题解 P2910 【[USACO08OPEN]寻宝之路Clear And Present Danger】

· · 题解

为啥各位都要用弗洛伊德

居然只有一位大佬用dijkstra...这题没有负边权,多好的一个dijkstra变式题。。。

然后我的脑回路比较清奇,三七二十一地一个一个点地求最短路然后加起来,可能是这个方法太弱智各位大佬都不想用,所以貌似没有这种题解。

于是本蒟蒻斗胆写一篇

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;

int g[101][101],n,m,dij,minn;
int list[10001],dis[101];
bool vis[101];

int dijkstra(int curr,int end)
{
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++) dis[i]=2e9;
    dis[curr]=0;
    while(!vis[end])
    {
        vis[curr]=true;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]) continue;
            if(dis[curr]+g[curr][i]>=dis[i]) continue;
            dis[i]=dis[curr]+g[curr][i];
        }
        minn=2e9;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]) continue;
            if(minn>=dis[i])
            {
                minn=dis[i];
                curr=i;
            }
        }
    }
    return dis[end];
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d",&list[i]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&g[i][j]);
    for(int i=1;i<m;i++)
        dij+=dijkstra(list[i],list[i+1]);
    printf("%d",dij);
    return 0;
}

各位大佬看到错的务必指正啊QAQ