zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第五场)A Portal 题解

    题意:

    n( n<=300 )个点m条边( m<=40000 )的带边权无向连通图,要求按顺序经过a1 b1 a2 b2 ……ak bk,( k<=300 )你有一个传送门,可以随时在脚下放置一个传送门,两个传送门之间可以相互传送,但场上最多同时存在两个传送门,你可以在任意时候关掉任意一个传送门。问走过这2k个点最短路程是多少。

    当时第一反应是设f[x][y][z]为在ak点打算走到bk点,传送门在y z时的最短路程,但是发现时间复杂度不对。后来想到这张图可以做最小生成树简化成一个树,这样路径就好找多了。然后发现有这么一个美妙的性质:当场上有两个传送门时,当且仅当我们站在一个传送门所在点时这两个传送门对我们都有意义,否则只有一个传送门对我们有意义。

    那么状态就可以简化了,我们设f[x][y]为在ak点,打算向bk点走,有一个传送门在y点时的最短路程,y=0 时说明场上还没有传送门。

    接下来,我们枚举是否在ak走向bk的过程中放置传送门,以及以怎样的路径放置。bk到ak+1的过程同理。

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<queue>
      5 #include<cmath>
      6 #include<cstring>
      7 #include<algorithm>
      8 #define N 305
      9 using namespace std;
     10 int n,m,zz,a[N],K;
     11 struct ro{
     12     int to,next,l;
     13 }road[N*N*2];
     14 void build(int x,int y,int z)
     15 {
     16     zz++;
     17     road[zz].to=y;
     18     road[zz].next=a[x];
     19     road[zz].l=z;
     20     a[x]=zz;
     21 }
     22 long long dis[N][N];
     23 queue<int > q1;
     24 bool rd[N];
     25 void spfa(int S)
     26 {
     27     memset(rd,0,sizeof(rd));
     28     rd[S]=1;q1.push(S);
     29     dis[S][S]=0;
     30     while(!q1.empty())
     31     {
     32         int x=q1.front();q1.pop();
     33         rd[x]=0;
     34         for(int i=a[x];i;i=road[i].next)
     35         {
     36             int y=road[i].to;
     37             if(dis[S][y]>dis[S][x]+road[i].l)
     38             {
     39                 dis[S][y]=dis[S][x]+road[i].l;
     40                 if(!rd[y])
     41                 {
     42                     rd[y]=1;
     43                     q1.push(y);
     44                 }
     45             }
     46         }
     47     }
     48 }
     49 int F[N][2];
     50 long long f[2][N];
     51 int main()
     52 {
     53     memset(dis,0x3f,sizeof(dis));
     54     scanf("%d%d%d",&n,&m,&K);
     55     for(int i=1;i<=m;i++)
     56     {
     57         int x,y,z;
     58         scanf("%d%d%d",&x,&y,&z);
     59         build(x,y,z);
     60         build(y,x,z);
     61     }
     62     for(int i=1;i<=n;i++)
     63     {
     64         spfa(i);
     65     }
     66     for(int i=1;i<=K;i++)
     67     {
     68         scanf("%d%d",&F[i][0],&F[i][1]);
     69     }
     70     int nw=1,la=0;
     71     long long mx;
     72     for(int j=0;j<=n;j++) f[0][j]=f[1][j]=1e15;
     73     mx=f[0][0];
     74     f[nw][0]=0;
     75     F[0][1]=1;
     76     for(int i=1;i<=K;i++)
     77     {
     78         nw^=1,la^=1;
     79         for(int j=0;j<=n;j++) f[nw][j]=1e15;
     80         int x=F[i-1][1],y=F[i][0];
     81         for(int j=0;j<=n;j++)
     82         {
     83             if(!j)
     84             {
     85                 f[nw][0]=min(f[nw][0],f[la][0]+dis[x][y]);
     86             }
     87             else
     88             {
     89                 f[nw][j]=min(f[nw][j],f[la][j]+dis[x][y]);
     90                 for(int k=0;k<=n;k++)
     91                 {
     92                     f[nw][j]=min(f[nw][j],f[la][k]+dis[x][j]+dis[j][y]);
     93                     f[nw][j]=min(f[nw][j],f[la][k]+dis[k][j]+dis[j][y]);
     94                     f[nw][j]=min(f[nw][j],f[la][k]+dis[k][j]+dis[k][y]);
     95                     f[nw][j]=min(f[nw][j],f[la][k]+dis[x][j]+dis[k][y]);
     96                 }
     97             }
     98         }
     99          
    100         nw^=1,la^=1;
    101         for(int j=0;j<=n;j++) f[nw][j]=1e15;
    102         x=F[i][0],y=F[i][1];
    103         for(int j=0;j<=n;j++)
    104         {
    105             if(!j)
    106             {
    107                 f[nw][0]=min(f[nw][0],f[la][0]+dis[x][y]);
    108             }
    109             else
    110             {
    111                 f[nw][j]=min(f[nw][j],f[la][j]+dis[x][y]);
    112                 for(int k=0;k<=n;k++)
    113                 {
    114                     f[nw][j]=min(f[nw][j],f[la][k]+dis[x][j]+dis[j][y]);
    115                     f[nw][j]=min(f[nw][j],f[la][k]+dis[k][j]+dis[j][y]);
    116                     f[nw][j]=min(f[nw][j],f[la][k]+dis[k][j]+dis[k][y]);
    117                     f[nw][j]=min(f[nw][j],f[la][k]+dis[x][j]+dis[k][y]);
    118                 }
    119             }
    120         }
    121     }
    122     long long ans=mx;
    123     for(int i=0;i<=n;i++)
    124     {
    125         ans=min(ans,f[nw][i]);
    126     }
    127     printf("%lld
    ",ans);
    128     return 0;
    129 }
    View Code
  • 相关阅读:
    java怎样将一组对象传入Oracle存储过程
    android webview内容压线问题解决方法
    BS和CS对比
    【OpenCV-Python】Python Extension Packages for Windows
    hdu4462 Scaring the Birds
    tomcat安全配置之证书密码加密存储
    UVA 10714 Ants 蚂蚁 贪心+模拟 水题
    一个不喜欢读书的Javaer的读书单
    二叉树可视化--Graphviz
    [置顶] mmog游戏开发之业务篇
  • 原文地址:https://www.cnblogs.com/liutianrui/p/13379400.html
Copyright © 2011-2022 走看看