• 【Floyd(并非水题orz)】BZOJ4093-[Usaco2013 Dec]Vacation Planning


    最近刷水太多标注一下防止它淹没在silver的水题中……我成为了本题,第一个T掉的人QAQ

    【题目大意】

    Bovinia设计了连接N (1 < = N < = 20,000)个农场的航班。对于任何航班,指定了其中的k个农场作为枢纽。 (1 < = K <= 200 , K < = N)。
    目前,共有M种单向航班( 1 < = M < = 20,000 ),第i个航班从农场u_i至农场v_i花费d_i ( 1 < = d_i < =10,000 )美元。航班保证u_i或者v_i至少有一个是枢纽,任意两个农场至多只有一个航班,保证u_i≠v_i。
    Bessie负责票务服务。共收到Q个度假请求,(1 < = Q < = 50,000),其中第i个请求是从农场a_i至农场b_i 。请帮助她计算,每个请求是否满足 ,并计算:能满足的度假请求的最小费用总和。
     
    【思路】
    首先我们会思考一个问题:为什么要给出中枢?显然这是一个不必要信息,即即使没有中枢本题也是可以求解的。那么只有一种可能性:优化。
    显然,每个非中枢的周围必定是中枢,也就是说,中枢间可以通过直接相连,或通过一个非中枢点连接。预处理 直接相连 或 间隔一个非中枢点 相连的两个中枢的距离,然后跑Floyd得出所有中枢之间的最短路。这里写堆优化dijkstra会快一些,然而我懒
    以下灰字是我脑补出来的T掉的做法。按照我的做法我们直接进入查询,如果ab都是中枢,用预处理的信息。否则就枚举旁边的中枢再加上边长。这样最糟糕的情况是两个都不是中枢,那么两边都要枚举。由于Q很大,这些时间复杂度都累在了Q里面,药丸。果然成为了该题第一个T掉的人。
    接下来处理出所有的中枢到所有节点之间的最短路。由于已知两个中枢(u,v)之间的最短路,对于从v出发抵达的下一个农场vv,很容易得到(u,vv)。
    最后对于查询的(a,b),如果a是一个中枢,直接可以利用上一步处理出来的信息。否则枚举a指向的每一个中枢c和b之间的最短路,再加上ac的距离,最小的那个即为最短路。
    我觉得USACO上算的时间复杂度有点诡。
    【错误点】
    第二次的dis[i][j]表示第i个中枢到农场j的距离,前一个是中枢的编号,后一个是农场的编号。
    写的时候老是弄晕掉。结果这道题写了我将近三分之二场noip的时间。
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int MAXK=200+5;
      5 const int MAXN=20000+50;
      6 const ll INF=1e12;
      7 struct node
      8 {
      9     int to,dis;
     10 };
     11 vector<node> E[MAXN];
     12 int n,m,k,q;
     13 ll d[MAXK][MAXK],dis[MAXK][MAXN];
     14 int id[MAXN],num[MAXN];
     15 
     16 void addedge(int u,int v,int w)
     17 {
     18     E[u].push_back((node){v,w}); 
     19 }
     20 
     21 void init()
     22 {
     23     scanf("%d%d%d%d",&n,&m,&k,&q);
     24     memset(id,0,sizeof(id));
     25 
     26     for (int i=1;i<=m;i++)
     27     {
     28         int u,v,w;
     29         scanf("%d%d%d",&u,&v,&w);
     30         addedge(u,v,w);
     31     }
     32     for (int i=1;i<=k;i++)
     33     {
     34         int x;
     35         scanf("%d",&x);
     36         id[x]=i,num[i]=x;
     37     }
     38 }
     39 
     40 void prep()
     41 {        
     42     for (int i=1;i<=k;i++)
     43         for (int j=1;j<=k;j++)
     44             d[i][j]=INF;
     45     for (int i=1;i<=k;i++) d[i][i]=0;
     46     for (int i=1;i<=k;i++)
     47     {
     48         int u=num[i];
     49         for (int j=E[u].size()-1;j>=0;j--)
     50         {
     51             int v=E[u][j].to;
     52             if (id[v]) d[i][id[v]]=min(d[i][id[v]],(ll)E[u][j].dis);
     53                 else
     54                 {
     55                     for (int _k=E[v].size()-1;_k>=0;_k--)
     56                     {
     57                         int vto=E[v][_k].to;
     58                         if (id[vto] && vto!=num[i]) d[id[u]][id[vto]]=min(d[id[u]][id[vto]],(ll)E[u][j].dis+(ll)E[v][_k].dis);
     59                     }
     60                 }
     61         }
     62     }    
     63     
     64     for (int _k=1;_k<=k;_k++)
     65         for (int i=1;i<=k;i++)
     66             for (int j=1;j<=k;j++)
     67                 if (i!=j && j!=_k && _k!=i) d[i][j]=min(d[i][j],d[i][_k]+d[_k][j]); 
     68 }
     69 
     70 void prep2()
     71 {
     72     for (int i=1;i<=k;i++)
     73         for (int j=1;j<=n;j++) dis[i][j]=INF;
     74     for (int i=1;i<=k;i++)
     75         for (int j=1;j<=k;j++) dis[i][num[j]]=d[i][j];
     76         
     77         
     78         
     79     for (int i=1;i<=k;i++)
     80     {
     81         for (int _k=0;_k<E[num[i]].size();_k++)//注意这里是E[num[i]]不是num[i],检查了40分钟才发现QAQ
     82             for (int j=1;j<=k;j++)
     83             {
     84                 int to=E[num[i]][_k].to;
     85                 dis[j][to]=min(dis[j][to],d[j][i]+E[num[i]][_k].dis);
     86             }
     87     }
     88 }
     89 
     90 void solve()
     91 {
     92     int t=0;
     93     ll totalans=0;
     94     for (int i=0;i<q;i++)
     95     {
     96         int a,b;
     97         scanf("%d%d",&a,&b);
     98         ll ans=INF;
     99         if (id[a]) ans=dis[id[a]][b];
    100             else
    101             {
    102                 for (int j=0;j<E[a].size();j++)
    103                 {
    104                     int v=E[a][j].to;
    105                     if (id[v]) ans=min(ans,E[a][j].dis+dis[id[v]][b]);
    106                 }
    107             }
    108         if (ans<INF)
    109         {
    110             totalans+=ans;
    111             t++;
    112         }
    113     }
    114     printf("%d
    ",t);
    115     printf("%d",totalans);
    116 }
    117 
    118 int main()
    119 {
    120     init();
    121     prep();
    122     prep2();
    123     solve();
    124     return 0;
    125 }
    126 
    127 /*
    128 TLE的solve,答案是正确的QAQ 
    129 void solve()
    130 {
    131     int t=0;
    132     ll totalans=0;
    133     for (int i=1;i<=q;i++)
    134     {
    135         int a,b;
    136         ll ans=INF;
    137         scanf("%d%d",&a,&b);
    138         if (id[a] && id[b]) ans=d[id[a]][id[b]];
    139         else if (id[a])
    140         {
    141             for (int ib=0;ib<rE[b].size();ib++) ans=min(ans,d[id[a]][id[rE[b][ib].to]]+(ll)rE[b][ib].dis);
    142         }
    143         else if (id[b])
    144         {
    145             for (int ia=0;ia<E[a].size();ia++) ans=min(ans,d[id[E[a][ia].to]][id[b]]+(ll)E[a][ia].dis);
    146         }
    147         else
    148         {
    149             for (int ia=0;ia<E[a].size();ia++)
    150                 for (int ib=0;ib<rE[b].size();ib++)
    151                 {
    152                     ll now=(ll)E[a][ia].dis+(ll)rE[b][ib].dis;
    153                     now+=d[id[E[a][ia].to]][id[rE[b][ib].to]];
    154                     ans=min(ans,now);
    155                 }
    156         }
    157         if (ans!=INF) t++,totalans+=ans;
    158     }
    159     printf("%d
    ",t);
    160     printf("%lld",totalans);
    161 }*/ 
  • 相关阅读:
    java读取xml文件的四种方法
    列表list常用的方法
    关于字符串的格式化----format与%
    安装爬虫常用包时出现的小问题
    Lniux系统-Ubantu安装搜狗输入法
    激活windows操作系统的命令行指令
    远程桌面连接的实现
    机器学习入门
    cookie,webstorage的理解
    设置窗口的自适应大小
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/6009786.html
Copyright © 2020-2023  润新知