zoukankan      html  css  js  c++  java
  • [NOIp 2015]运输计划

    Description

    公元 2044 年,人类进入了宇宙纪元。

    L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球。

    小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道 是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之 间不会产生任何干扰。

    为了鼓励科技创新,L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小 P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。

    在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后, 这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的 物流公司的阶段性工作就完成了。

    如果小 P 可以自由选择将哪一条航道改造成虫洞,试求出小 P 的物流公司完成阶段 性工作所需要的最短时间是多少?

    Input

    第一行包括两个正整数 n、m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。

    接下来 n-1 行描述航道的建设情况,其中第 i 行包含三个整数 ai, bi 和 ti,表示第i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。

    接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j个 运输计划是从 uj 号星球飞往 vj 号星球。

    Output

    输出 共1行,包含1个整数,表示小P的物流公司完成阶段性工作所需要的最短时间。

    Sample Input

    6 3 
    1 2 3 
    1 6 4 
    3 1 7 
    4 3 6 
    3 5 5 
    3 6 
    2 5 
    4 5

    Sample Output

    11

    Sample Explanation

    Hint

    题解

    抓取有用信息:

    1、给定一棵$n$个点的带边权的树,给定$m$条路径;
    2、求将任意一条边的边权置为$0$后所有路径长度最大值的最小值。

    20分算法:

    1、由于是一棵树,所以所有的路径都是最短路径,结合题目给定的数据范围,可以用合适的数据结构解决;
    2、枚举被操作的边,$DFS$统计所有路径长度的最大值,然后更新答案;
    3、时间复杂度$O(n^2*m)$。

    40分算法:

    1、枚举被操作的边,使用树链剖分等树上数据结构统计所有路径长度的最大值,然后更新答案;
    2、时间复杂度$O(n^2log_2n)$。

    60分算法:

    1、先使用各种方法预处理出$LCA$,枚举被操作的边;
    2、$DFS$在$O(n)$时间内统计所有路径的长度的最大值,然后更新答案;
    3、时间复杂度$O(n^2)$。
    如何用$DFS$在$O(n)$时间内统计所有路径的长度的最大值?
    计算每一点到根的路径$dis[i]$,所以:
    $$dist(u,v)=dis[u]+dis[v]-2*dis[LCA(u,v)]$$

    100分算法:

    1、先使用各种方法预处理出$LCA$与路径在未操作前的长度,推荐使用$Trajan$算法;
    2、二分答案,即二分出路径长度的最大值$X$;
    3、将所有长度大于$X$的路径找出来,求出最长的路径长度与$X$的差值$D$;
    4、那么显然被删掉的边,边权$≥D$;然后使用各种方法求出这些路径的并集
    (欧拉$DFS$序列或树上差分序列),看这些边的并集中是否有一条边的边权$≥D$,若有则该$X$可行。
    5、时间复杂度$O(nlog_2n)$。

      1 #include<set>
      2 #include<map>
      3 #include<ctime>
      4 #include<cmath>
      5 #include<queue>
      6 #include<stack>
      7 #include<vector>
      8 #include<cstdio>
      9 #include<string>
     10 #include<cstring>
     11 #include<cstdlib>
     12 #include<iostream>
     13 #include<algorithm>
     14 #define LL long long
     15 #define Max(a,b) ((a)>(b) ? (a):(b))
     16 #define Min(a,b) ((a)<(b) ? (a):(b))
     17 using namespace std;
     18 const int N=300000;
     19 
     20 int n,m,u,v,c,lim;
     21 struct tt
     22 {
     23     int to,cost,next;
     24 }edge[N*2+5];
     25 int path[N+5],top;
     26 void Add(int u,int v,int c);
     27 struct ss
     28 {
     29     int a,b,lca,cost;
     30 }p[N+5];
     31 int fa[N+5][20],dist[N+5],dep[N+5];
     32 void Dfs(int r,int depth);
     33 void ST();
     34 void LCA(int k);
     35 
     36 int vis[N+5],cnt;
     37 bool work(int r);
     38 int judge(int r,int father);
     39 
     40 int main()
     41 {
     42     scanf("%d%d",&n,&m);
     43     lim=log(n)/log(2);
     44     for (int i=1;i<n;i++)
     45     {
     46       scanf("%d%d%d",&u,&v,&c);
     47       Add(u,v,c);
     48       Add(v,u,c);
     49     }
     50     for (int i=1;i<=m;i++) scanf("%d%d",&p[i].a,&p[i].b);
     51     Dfs(1,1);
     52     ST();
     53     int maxlenth=0;
     54     for (int i=1;i<=m;i++)
     55     {
     56       LCA(i);
     57       if (p[i].cost>maxlenth) maxlenth=p[i].cost;
     58     }
     59     int l=0,r=maxlenth,ans=maxlenth;
     60     while (l<=r)
     61     {
     62       int mid=(l+r)>>1;
     63       if (work(mid)) ans=mid,r=mid-1;
     64       else l=mid+1;
     65     }
     66     printf("%d
    ",ans);
     67     return 0;
     68 }
     69 
     70 void Add(int u,int v,int c)
     71 {
     72     edge[++top].to=v;
     73     edge[top].cost=c;
     74     edge[top].next=path[u];
     75     path[u]=top;
     76 }
     77 void Dfs(int r,int depth)
     78 {
     79     dep[r]=depth;
     80     for (int i=path[r];i;i=edge[i].next) if (!dep[edge[i].to])
     81     {
     82       fa[edge[i].to][0]=r;
     83       dist[edge[i].to]=dist[r]+edge[i].cost;
     84       Dfs(edge[i].to,depth+1);
     85     }
     86 }
     87 void ST()
     88 {
     89     for (int t=1;t<=lim;t++)
     90       for (int i=1;i<=n;i++)
     91           fa[i][t]=fa[fa[i][t-1]][t-1];
     92 }
     93 void LCA(int k)
     94 {
     95     int a=p[k].a,b=p[k].b;
     96     if (dep[a]<dep[b]) swap(a,b);
     97     for (int i=lim;i>=0;i--) if (dep[fa[a][i]]>=dep[b]) a=fa[a][i];
     98     if (a!=b)
     99     {
    100       for (int i=lim;i>=0;i--) if (fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i];
    101       a=fa[a][0],b=fa[b][0];
    102     }
    103     p[k].lca=a;
    104     p[k].cost=dist[p[k].a]+dist[p[k].b]-2*dist[p[k].lca];
    105 }
    106 bool work(int r)
    107 {
    108     memset(vis,0,sizeof(vis));
    109     cnt=0;
    110     int maxlenth=0;
    111     for (int i=1;i<=m;i++)
    112       if (p[i].cost>r)
    113       {
    114           cnt++,maxlenth=Max(maxlenth,p[i].cost);
    115           vis[p[i].a]++,vis[p[i].b]++,vis[p[i].lca]-=2;
    116       }
    117     int delta=maxlenth-r;
    118     maxlenth=judge(1,0);
    119     return maxlenth>=delta;
    120 }
    121 int judge(int r,int father)
    122 {
    123     int ans=0;
    124     for (int i=path[r];i;i=edge[i].next) if (edge[i].to!=father)
    125     {
    126       int tmp=judge(edge[i].to,r);
    127       ans=Max(ans,tmp);
    128       vis[r]+=vis[edge[i].to];
    129     }
    130     if (vis[r]==cnt) ans=Max(ans,dist[r]-dist[fa[r][0]]);
    131     return ans;
    132 }
  • 相关阅读:
    Robot Framework(十八) 支持工具
    Robot Framework(十七) 扩展RobotFramework框架——扩展Robot Framework Jar
    Robot Framework(十六) 扩展RobotFramework框架——使用监听器接口
    Robot Framework(十五) 扩展RobotFramework框架——远程库接口
    Robot Framework(十四) 扩展RobotFramework框架——创建测试库
    Robot Framework(十三) 执行测试用例——创建输出
    Robot Framework(十二) 执行测试用例——配置执行
    Robot Framework(十一) 执行测试用例——后处理输出
    Robot Framework(十) 执行测试用例——测试执行
    ivew中,table里面的按钮,render里面删除按钮的二次确认
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7445989.html
Copyright © 2011-2022 走看看