• [USACO13DEC]假期计划(黄金)Vacation Planning (gold)


    题目翻译不好,这里给出一份

    题目背景

    Awson是某国际学校信竞组的一只大佬。由于他太大佬了,于是干脆放弃了考前最后的集训,开车(他可是老司机)去度假。离开学校前,他打开地图,打算做些规划。

    题目描述

    他发现整个地图中有N(1<=N<=20000)个地点。对于所有的路线,指定了其中K(1<=K<=200,K<=N)个地点作为收费站。他设计了M(1<=M<=20000 )种单向的路线,第i条路线从地点Ui至Vi收费为Di(1<=Di<=10000)。路线保证Ui或Vi至少有一个是收费站,且Ui≠Vi,任意两个地点至多有一条路线。现在Awson准备进行规划。共提出Q(1<=Q<=50000)个询问,其中第i个询问是从地点Ai至地点Bi。请帮助他计算,每个请求是否满足(是否从地点Ai至地点Bi有可行路线),并计算:能满足的度假询问的最小费用总和。

    输入输出格式

    输入格式:

    第1行:四个整数N,M,K,Q

    第2~M+1行:三个整数Ui,Vi,Di

    第M+2~M+K+1行:收费站的编号X (0<=X<=N)

    第M+K+2~M+K+Q+1:两个整数,度假询问Ai,Bi

    输出格式:

    第1行:能够满足的度假询问数

    第2行:能满足的度假询问的最小费用总和

    输入输出样例

    输入样例:

    3 3 1 2
    1 2 10
    2 3 10
    2 1 5
    2
    1 3
    3 1

    输出样例:

    1
    20

    说明

    样例解释:

    第1个询问,路线设计为1->2->3,费用为20
             第2个询问,无法满足

    数据规模:

    30%的数据有N<=100;

    100%的数据有1<=N,M<=20000,1<=Q<=50000。

    题解:

    n很大,就算能O(1)求最短路也不行

    但我们发现k很小,而且每条边至少有一个收费站

    假设问u,v之间的最小距离,就是与u相邻的收费站与v的距离+边权

    为包括u是收费站的情况,加入(u,u,0)边,修改部分会在代码中标记

    题目转化为了求每个收费站到每个点的距离,用SPFA

    复杂度为O(km+k*k)

    询问部分可知一个点相邻的收费站最多为k,所以

    询问复杂度为O(Q*k)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct Node
     7 {
     8     int next,dis,to;
     9 }edge[200001];
    10 int head[100001],num,dist[201][20001],q[1000001],n,m,k,Q,p[10001],dis[301][301],b[100001],ans,cnt;
    11 bool vis[100001];
    12 void add(int u,int v,int d)
    13 {
    14     num++;
    15     edge[num].next=head[u];
    16     head[u]=num;
    17     edge[num].to=v;
    18     edge[num].dis=d;
    19 }
    20 void SPFA(int st,int j)
    21 {int h,t,i;;
    22     memset(dist[j],127,sizeof(dist[j]));
    23     memset(vis,0,sizeof(vis));
    24     q[1]=st;
    25      h=0;t=1;
    26      dist[j][st]=0;
    27      while (h<t)
    28      {
    29         h++;
    30         h%=1000000;
    31         int u=q[h];
    32         vis[u]=0;
    33          for (i=head[u];i;i=edge[i].next)
    34          {
    35             int v=edge[i].to;
    36             if (dist[j][v]>dist[j][u]+edge[i].dis)
    37             {
    38                 dist[j][v]=dist[j][u]+edge[i].dis;
    39                 if (!vis[v])
    40                 {
    41                     t++;
    42                     t%=1000000;
    43                     q[t]=v;
    44                     vis[v]=1;
    45                 }
    46             }    
    47          } 
    48      }
    49      for (i=1;i<=k;i++)
    50      if (i!=j)
    51      dis[j][i]=dist[j][p[i]];
    52 }
    53 int main()
    54 {int i,j,u,v,d;
    55     cin>>n>>m>>k>>Q;
    56     edge[0].next=-1;
    57     for (i=1;i<=m;i++)
    58     {
    59       scanf("%d%d%d",&u,&v,&d);
    60       add(u,v,d);
    61     }
    62      for (i=1;i<=k;i++)
    63      {
    64         scanf("%d",&p[i]);
    65         b[p[i]]=i;
    66      }
    67      for (i=1;i<=k;i++)
    68      {
    69          SPFA(p[i],i);
    70      }
    71       while (Q--)
    72       {
    73             scanf("%d%d",&u,&v);
    74             int s=1e9,x,y;
    75             if (b[u]&&b[v]) 
    76              {
    77                 s=dis[b[u]][b[v]];
    78              }
    79              else
    80             for (i=head[u];i!=-1;i=edge[i].next)
    81             {
    82                 if (b[u]) i=0;
    83                 if (i==0) x=u;
    84                 else x=edge[i].to;
    85                 if (b[x])
    86                  {
    87                     if (s>edge[i].dis+dist[b[x]][v]) 
    88                      s=edge[i].dis+dist[b[x]][v];
    89                  }
    90             }
    91             //cout<<s<<endl;
    92         if (s<1e9)
    93           ans+=s,cnt++;
    94       }
    95       cout<<cnt<<endl<<ans;
    96 }
  • 相关阅读:
    网络嗅探与协议分析之验收题
    20199121《网络攻防实践》第四周作业
    如何设计一个卡方检验
    20199121《网络攻防实践》第三周作业
    openssl制作证书全过程及https实现
    Padding Oracle攻击解密AES
    virt-sysprep命令清理缓存文件时失败的解决方法
    OpenStack的centos镜像制作
    KVM--Host does not support any virtualization...
    Centos7 安装VNC实现远程桌面
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7365061.html
Copyright © 2020-2023  润新知