zoukankan      html  css  js  c++  java
  • usaco 奶牛接力

    Description

    为增强体质,约翰决定举办一场奶牛接力跑比赛。比赛现场有一些接力位置,这些位置间有T条路连接,第i条路的长度为Li。 有N头奶牛需要参加比赛,领头的奶牛从位置S出发,她会按照你的指示沿着一条路跑到下个位置,把接力棒交给等在那里的下一头奶牛,就休息去了。每头奶牛重复这个过程这条接力路线的终点必须在位置E上。

    奶牛数量较多,允许一些奶牛等候在同一位置,一条路也可以供多头奶牛奔跑。 奶牛们对接力跑兴趣不大,拜托你敷衍地设计一条总长度最短的路线。所以请设计一条由N段路组成的,起点在S,终点在E上的最短路线吧。

    Input Format

    第一行:四个用空格分开的整数:表示N,T,S和E,2 ≤ N ≤ 106,2 ≤ T ≤ 100,1 ≤ S, E ≤ 1000

    第二行到T + 1行: 第i + 1行首先有一个正整数Li,表示第i条路的长度, 1 ≤ Li ≤ 1000,其次是Ui和Vi,表示第i条路连接的两个位置,1 ≤ Ui, Vi ≤ 1000

    Output Format

    第一行:单个整数,表示起点为S,终点为E,且恰好经过N段路的最短路线长度

    ------------------------------------------------------

    正解 = 最短路+倍增+(貌似有个很傻的离散- =)

    注意道题目中的 N 比较大,T却很小- =,

    由于 Ui 与 Vi 的范围比 T 还大,显然中间有许多无用的点

    离散之,

    注意道题目中的 N 比较大,T却很小- =,

    这说明一个点会被经过多次(显然),

    原本最短路只能得到任意两点 i,j 的距离dis[i][j],

    在这个基础上加一维 dis[i][j][k] 表示 i 到 j 且经过2k条路径的最短路径,

    转移于folyed有些类似 dis[i][j][k]=dis[i][p][k-1]+dis[p][j][k-1](p为图中的点)

    将 N 转为2进制 设为 T2,设f[i][j]为 从起点S 到 i 这个点经过了 (T2从左往右数j个1达到的值)条路径

    f[i][j]=f[k][j-1]+dis[i][k][p](k为图中点)(p为 2^p

    f[终点][T2 中 1 的个数]即为所求答案- =

    Ps.好吧,我承认我表达能力挺拙计的- =

    代码如下:

     1 #include<cstring>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<string>
     5 #include<iostream>
     6 #include<queue>
     7 #define INF 999999999
     8 #define min(x,y) if(x>y||x==-1) x=y
     9 int P,dis[102][102][30],f[102][30],N,T,S,E;
    10 int O, ok[2000];
    11 void Do(){
    12    for(int p=1;(1<<p)<=N;p++)
    13     for(int i=1;i<=O;i++)
    14       for(int j=1;j<=O;j++)
    15         for(int k=1;k<=O;k++)
    16           if(dis[i][j][p]>dis[i][k][p-1]+dis[k][j][p-1])
    17             dis[i][j][p]=dis[i][k][p-1]+dis[k][j][p-1];
    18 }
    19 void Dp(){
    20     for(int i=0;i<=100;i++) 
    21       for(int k=0;k<=50;k++) 
    22         f[i][k]=INF;
    23     f[ok[S]][0]=0;
    24     int k=0,p=0;
    25     while(N){
    26         if(N&1){
    27           ++k;
    28           for(int i=1;i<=O;i++)
    29            for(int j=1;j<=O;j++)
    30             if(f[i][k]>f[j][k-1]+dis[i][j][p])         
    31              f[i][k]=f[j][k-1]+dis[i][j][p];
    32         }
    33         N>>=1;
    34         ++p;
    35     }
    36     printf("%d",f[ok[E]][k]);
    37 }
    38 int main(){
    39     scanf("%d%d%d%d",&N,&T,&S,&E);
    40     for(int i=0;i<=100;i++)
    41       for(int j=0;j<=100;j++)
    42         for(int k=0;k<=30;k++)
    43           dis[i][j][k]=INF;
    44     for(int i=1;i<=T;i++){
    45         int u,v,t;
    46         scanf("%d%d%d",&t,&u,&v);
    47         if(!ok[u]) ok[u]=++O;
    48         if(!ok[v]) ok[v]=++O;
    49         dis[ok[u]][ok[v]][0]=dis[ok[v]][ok[u]][0]=t;
    50     }
    51     Do(); 
    52     Dp();
    53 }
    View Code
  • 相关阅读:
    一个很香的python练习网站
    关于接口测试用例设计的一些思考
    pytest、tox、Jenkins实现python接口自动化持续集成
    django实战商城项目注册业务实现
    面试测试开发被问到数据库索引不知道怎么办?这篇文章告诉你
    python框架Django实战商城项目之用户模块创建
    python框架Django实战商城项目之工程搭建
    golang在gitlab中的工作流
    kubernetes extension point
    kubernetes controller 实现
  • 原文地址:https://www.cnblogs.com/Blacko/p/3383139.html
Copyright © 2011-2022 走看看