30分dijkstra求调
查看原帖
30分dijkstra求调
1419923
ZYStream楼主2024/12/12 21:41
#include<cstdio>
#include<vector>
#include<queue>
#include<climits>
using namespace std;
#define int long long

int ans=0;
int n,m,now,now1;
struct Edge{
    int v,w;
};
vector<Edge> g[105];
int a[10005];
int vis[105];
int dis[105][105];
struct node{
    int dis,u;
    bool operator>(const node &a) const{
        return a.dis<dis;
    }
};
priority_queue<node,vector<node>,greater<node>> q;

void dijkstra(int u){
    dis[now][now]=0;
    q.push((node){0,u});
    while (!q.empty()){
        int u=q.top().u;
        q.pop();
        if (u==now1) break ;
        if (vis[u]) continue;
        vis[u]=1;
        for (Edge ed:g[u]){
            int v=ed.v,w=ed.w;
            if (dis[now][v]>dis[now][u]+w){
                dis[now][v]=dis[now][u]+w;
                q.push((node){dis[now][v],v});
            }
        }
    }
}

signed main(){
    scanf("%lld%lld",&n,&m);
    for (int i=1;i<=m;i++) scanf("%lld",&a[i]);
    for (int i=1;i<=n;i++){
        for (int j=1;j<=n;j++){
            int w;
            scanf("%lld",&w);
            if (i==j) continue;
            g[i].push_back((Edge){j,w});
        }
    }
//从第一个点出发到a1的最短路
    for (int j=1;j<=n;j++) vis[j]=0;
    for (int j=1;j<=n;j++) dis[1][j]=INT_MAX-1;
    now=1;
    now1=a[1];
    dijkstra(1);
    ans+=dis[1][now1];

    for (int i=2;i<=m;i++){
        for (int j=1;j<=n;j++) vis[j]=0;
        now=a[i-1];
        now1=a[i];
        for (int j=1;j<=n;j++) dis[now][j]=INT_MAX-1;
        if (dis[now][now1]!=INT_MAX-1){
            ans+=dis[now][now1];
            continue;
        }
        else{
            dijkstra(now);
            ans+=dis[now][now1];
        }
    }
    printf("%lld",ans);
    return 0;
}
2024/12/12 21:41
加载中...