• 2019牛客暑期多校训练营(第四场)J free(分层图最短路/模板题)


    题目链接:https://ac.nowcoder.com/acm/contest/884/J

    题目大意:

      给出一个无向图,每条边对应一个花费,有k次机会能让一条边的花费为0,让求s到t的最短路。

    解题报告:

      分层图最短路,就当是模板吧,下面给出两份AC代码。

      建图大概长这样

      

    AC代码:

      1.直接暴力建图,花费空间和时间较大。

      语言:C++ 代码长度:2264 运行时间: 269 ms 占用内存:121836K

     1 #include<bits/stdc++.h>
     2 #define numm ch-48
     3 #define pd putchar(' ')
     4 #define pn putchar('
    ')
     5 #define pb push_back
     6 #define fi first
     7 #define se second
     8 #define fre1 freopen("1.txt","r",stdin)
     9 #define fre2 freopen("3.txt","w",stdout)
    10 #define bug cout<<"*******************"<<endl;
    11 #define debug(args...) cout<<#args<<"->"<<args<<"
    ";
    12 using namespace std;
    13 template <typename T>
    14 void read(T &res) {
    15     bool flag=false;char ch;
    16     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
    17     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
    18     flag&&(res=-res);
    19 }
    20 template <typename T>
    21 void write(T x) {
    22     if(x<0) putchar('-'),x=-x;
    23     if(x>9) write(x/10);
    24     putchar(x%10+'0');
    25 }
    26 typedef long long ll;
    27 typedef unsigned long long ull;
    28 const int maxn=9003010; ///n*(k+1)
    29 const int maxm=505;
    30 const int mod=1e9+7;
    31 const int inv2=500000004;
    32 const int inf=0x3f3f3f3f;
    33 const ll INF=0x3f3f3f3f3f3f3f3f;
    34 const int N=32;
    35 struct node {
    36     int v,net,w;
    37 }e[maxn<<2];    ///分层图层和层之前也有边,边*4
    38 int head[maxn],dis[maxn],vis[maxn];
    39 #define pr pair<int,int>
    40 int S,T,cnt;
    41 void add(int u,int v,int w) {
    42     e[++cnt]={v,head[u],w};
    43     head[u]=cnt;
    44 }
    45 void dijstra() {
    46     priority_queue<pr,vector<pr>,greater<pr> >que;
    47     memset(dis,inf,sizeof(dis));
    48     que.push(make_pair(0,S));
    49     dis[S]=0;
    50     while(!que.empty()) {
    51         int u=que.top().se;que.pop();
    52         if(vis[u]) continue;
    53         vis[u]=true;
    54         for(int i=head[u];~i;i=e[i].net) {
    55             int v=e[i].v,w=e[i].w;
    56             if(!vis[v]&&dis[v]>dis[u]+w) {
    57                 dis[v]=dis[u]+w;
    58                 que.push(make_pair(dis[v],v));
    59             }
    60         }
    61     }
    62 }
    63 int main()
    64 {
    65 //    #define local
    66     #ifdef local
    67         fre1;
    68         fre2;
    69     #endif // local
    70     int n,m,k;
    71     memset(head,-1,sizeof(head));
    72     read(n),read(m),read(S),read(T),read(k);
    73     for(int i=1;i<=m;i++) {
    74         int u,v,w;
    75         read(u),read(v),read(w);
    76         for(int j=0;j<=k;j++) {
    77             add(u+j*n,v+j*n,w);
    78             add(v+j*n,u+j*n,w);
    79             if(j!=k) {
    80                 add(u+j*n,v+(j+1)*n,0);
    81                 add(v+j*n,u+(j+1)*n,0);
    82             }
    83         }
    84     }
    85     dijstra();
    86     int minn=inf;
    87     for(int i=0;i<=k;i++)
    88         minn=min(minn,dis[T+i*n]);
    89     write(minn);pn;
    90     return 0;
    91 }

      2.用数组标记状态,省空间也省时间

      语言:C++ 代码长度:2374 运行时间: 214 ms 占用内存:43628K

     1 #include<bits/stdc++.h>
     2 #define numm ch-48
     3 #define pd putchar(' ')
     4 #define pn putchar('
    ')
     5 #define pb push_back
     6 #define fi first
     7 #define se second
     8 #define fre1 freopen("1.txt","r",stdin)
     9 #define fre2 freopen("3.txt","w",stdout)
    10 #define bug cout<<"*******************"<<endl;
    11 #define debug(args...) cout<<#args<<"->"<<args<<"
    ";
    12 using namespace std;
    13 template <typename T>
    14 void read(T &res) {
    15     bool flag=false;char ch;
    16     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
    17     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
    18     flag&&(res=-res);
    19 }
    20 template <typename T>
    21 void write(T x) {
    22     if(x<0) putchar('-'),x=-x;
    23     if(x>9) write(x/10);
    24     putchar(x%10+'0');
    25 }
    26 typedef long long ll;
    27 typedef unsigned long long ull;
    28 const int maxn=3010; ///n*(k+1)
    29 const int maxm=505;
    30 const int mod=1e9+7;
    31 const int inv2=500000004;
    32 const int inf=0x3f3f3f3f;
    33 const ll INF=0x3f3f3f3f3f3f3f3f;
    34 const int N=32;
    35 struct node {
    36     int v,net,w;
    37 }e[maxn<<1];    ///分层图层和层之前也有边,边*4
    38 int head[maxn];
    39 int dis[maxn][maxn],vis[maxn][maxn];
    40 ///dis[i][k],用掉k次机会到达i点的花费
    41 #define pr pair<int,int>
    42 int S,T,cnt,n,k;
    43 void add(int u,int v,int w) {
    44     e[++cnt]={v,head[u],w};
    45     head[u]=cnt;
    46 }
    47 void dijstra() {
    48     priority_queue<pr,vector<pr>,greater<pr> >que;
    49     memset(dis,inf,sizeof(dis));
    50     que.push(make_pair(0,S-1));
    51     dis[S][0]=0;
    52     while(!que.empty()) {
    53         int u=que.top().se;que.pop();
    54         int c=u/n;u=u%n+1;
    55         if(vis[u][c]) continue;
    56         vis[u][c]=true;
    57         for(int i=head[u];~i;i=e[i].net) {
    58             int v=e[i].v,w=e[i].w;
    59             if(!vis[v][c]&&dis[v][c]>dis[u][c]+w) {  ///先不用机会到达下一顶点
    60                 dis[v][c]=dis[u][c]+w;
    61                 que.push(make_pair(dis[v][c],v-1+c*n));
    62             }
    63             if(c!=k&&!vis[v][c+1]&&dis[v][c+1]>dis[u][c]) {
    64                 dis[v][c+1]=dis[u][c];
    65                 que.push(make_pair(dis[v][c+1],v-1+(c+1)*n));
    66             }
    67         }
    68     }
    69 }
    70 int main()
    71 {
    72 //    #define local
    73     #ifdef local
    74         fre1;
    75         fre2;
    76     #endif // local
    77     int m;
    78     memset(head,-1,sizeof(head));
    79     read(n),read(m),read(S),read(T),read(k);
    80     for(int i=1;i<=m;i++) {
    81         int u,v,w;
    82         read(u),read(v),read(w);
    83         add(u,v,w);
    84         add(v,u,w);
    85     }
    86     dijstra();
    87     int minn=inf;
    88     for(int i=0;i<=k;i++)
    89         minn=min(minn,dis[T][i]);
    90     write(minn);pn;
    91     return 0;
    92 }
  • 相关阅读:
    su和sudo命令详解
    JS线程Web worker
    Navicat 批处理 自动备份数据库
    MySql【Error笔记】
    vue入门
    动态库
    环境变量
    cmake_learn
    自动编译
    网络编程
  • 原文地址:https://www.cnblogs.com/wuliking/p/11376419.html
Copyright © 2020-2023  润新知