zoukankan      html  css  js  c++  java
  • 牛客多校第四场 J Free 最短路

    题意:

    求最短路,但是你有k次机会可以把路径中某条边的长度变为0.

    题解:

    跑k+1次迪杰斯特拉,设想有k+1组dis数组和优先队列,第k组就意味着删去k条边的情况,每次松弛操作,松弛的两点i,j和距离l(i,j),不仅更新本组的dis数组令dis[j]=dis[i]+l[i,j],还更新下一组,令dis`[j]=dis[i],相当于删去边(i,j)

    #include<iostream>
    #include<queue>
    #include<vector>
    #include<cstring>
    #define INF 0x3f3f3f3f
    struct Point{
        int n,dis;
        friend bool operator >(const Point &a,const Point &b){
            return a.dis>b.dis;
        }
        friend bool operator <(const Point &a,const Point &b){
            return a.dis<b.dis;
        }
        Point(){}
        Point(int a,int b){
            n=a;dis=b;
        }
    };
    using namespace std;
    int lik[1003][1003];
    int dis[1003][1003];//删去了i条边后第j个点最短距离
    priority_queue<Point,vector<Point>,greater<Point> > que[1003];
    vector<Point>link[1003];
    int main(){
        int n,m,s,t,k;
        scanf("%d %d %d %d %d",&n,&m,&s,&t,&k);
         
        memset(dis,INF,sizeof dis);
        memset(lik,INF,sizeof lik);
        for(int i=1;i<=m;i++){
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            if(a==b)continue;
            else{
                lik[a][b]=min(lik[a][b],c);
                lik[b][a]=min(lik[b][a],c);
            }
        }
         
    //  for(int i=1;i<=n;i++){
    //      for(int j=1;j<=n;j++){
    //          printf("%d ",lik[i][j]);
    //      }
    //      printf("
    ");
    //  }
         
        for(int i=1;i<n;i++){
            for(int j=i+1;j<=n;j++){
                if(lik[i][j]<INF){
                    link[i].push_back(Point(j,lik[i][j]));
                    link[j].push_back(Point(i,lik[j][i]));
                }
                 
            }
        }
         
    //  for(int i=1;i<=n;i++)printf("%d ",link[i].size());
         
    //  system("pause");
        que[0].push(Point(s,0));
        dis[0][s]=0;
         
        for(int i=0;i<=k;i++){
            while(!que[i].empty()){
                 
                Point tmp=que[i].top();
                que[i].pop();
                int u=tmp.n;
                int nowd=tmp.dis;
                if(nowd>dis[i][u])continue;
                 
    //          printf("*%d %d
    ",u,nowd);
                 
                for(int j=0;j<link[u].size();j++){
                    int v=link[u][j].n;
                    int d=link[u][j].dis;
                     
                    if(dis[i][v]>nowd+d){
                        dis[i][v]=nowd+d;
                        que[i].push(Point(v,dis[i][v]));
                    }
                     
                    if(i<k && dis[i+1][v]>nowd){
                        dis[i+1][v]=nowd;
                        que[i+1].push(Point(v,dis[i+1][v]));
                    }
                     
    //              for(int w=0;w<=k;w++){
    //                  for(int r=1;r<=n;r++){
    //                      printf("%d ",dis[w][r]);
    //                  }
    //                  printf("
    ");
    //              }
    //              printf("
    ");
                     
                }
                 
            }
        }
    //  for(int w=0;w<=k;w++){
    //      for(int r=1;r<=n;r++){
    //          printf("%d ",dis[w][r]);
    //      }
    //      printf("
    ");
    //  }
        int minn=INF;
        for(int i=0;i<=k;i++){
            minn=min(minn,dis[i][t]);
        }
        printf("%d
    ",minn);
    }
  • 相关阅读:
    定时器
    按键中断部分的理解
    初中数学
    WING IDE 快捷键
    机器学习各种网址
    SQL With As 用法Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介
    Python编码格式导致的csv读取错误
    Oracle中的rownum 和rowid的用法和区别
    oracle配置
    matplotlib命令与格式:标题(title),标注(annotate),文字说明(text)
  • 原文地址:https://www.cnblogs.com/isakovsky/p/11257352.html
Copyright © 2011-2022 走看看