• [NOIP 2013]货车运输


    想要求货车的最大载重量,根据木桶原理,我们就希望一条路径上的载重量的最小值最大。让一条路径上的载重量的最小值最大,贪心得想,如果我加进去的每条边都是剩余边中最大的那一个,那么在形成完整的通路时,一条路径上的边一定是所有情况中最大的那一种,这个思想很明显就是最大生成树。

    LCA找路径求最小值就好了。

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 using namespace std;
      5 const int maxn=1e5+10;
      6 const int inf=1e9;
      7 int n,m;
      8 struct edge{
      9     int to,next,w;
     10 }ed[maxn];
     11 struct node{
     12     int x,y,dis;
     13 }pos[maxn];
     14 int head[maxn],tot;
     15 void add(int u,int to,int w){
     16     ed[++tot].w=w;
     17     ed[tot].to=to;
     18     ed[tot].next=head[u];
     19     head[u]=tot;
     20 }
     21 int fa[maxn];
     22 void init(){
     23     for(int i = 1;i <= n;i++) fa[i]=i;
     24 }
     25 int find(int x){
     26     if (fa[x]==x) return x;
     27     else return fa[x]=find(fa[x]);
     28 }
     29 void update(int x,int y){
     30     int fx=find(x),fy=find(y);
     31     fa[fx]=fy;
     32 }
     33 bool cmp(node x,node y){
     34     return x.dis>y.dis;
     35 }
     36 void tree(){
     37     sort(pos+1,pos+m+1,cmp);
     38     init();
     39     for (int i = 1;i <= m;i++){
     40         int x=pos[i].x,y=pos[i].y,w=pos[i].dis;
     41         if (find(x)!=find(y)){
     42             update(find(x),find(y));
     43             add(x,y,w);add(y,x,w);
     44         }
     45     }
     46 }
     47 int vis[maxn],dep[maxn],w[maxn][30],f[maxn][30];
     48 void dfs(int x){
     49     vis[x]=1;
     50     for (int i = head[x];i;i=ed[i].next){
     51         int to=ed[i].to;
     52         if (vis[to]) continue;
     53         dep[to]=dep[x]+1;
     54         f[to][0]=x;
     55         w[to][0]=ed[i].w;
     56         dfs(to);
     57     }
     58 }
     59 int lca(int x,int y){
     60     if (find(x)!=find(y)) return -1;
     61     int ans=inf;
     62     if (dep[x]>dep[y]) swap(x,y);
     63     for (int i = 20;i >= 0;i--){
     64         if (dep[f[y][i]]>=dep[x]){
     65             ans=min(ans,w[y][i]);
     66             y=f[y][i];
     67         }
     68     }
     69     if (x==y) return ans;
     70     for (int i = 20;i>= 0;i--){
     71         if (f[x][i]!=f[y][i]){
     72             ans=min(ans,min(w[x][i],w[y][i]));
     73             x=f[x][i];
     74             y=f[y][i];
     75         }
     76     }
     77     ans=min(ans,min(w[x][0],w[y][0]));
     78     return ans;
     79 }
     80 int main(){
     81     int x,y,z,q;
     82     scanf ("%d%d",&n,&m);
     83     for (int i = 1;i <= m;i++){
     84         scanf ("%d%d%d",&x,&y,&z);
     85         pos[i].x=x,pos[i].y=y,pos[i].dis=z;
     86     }
     87     tree();
     88     for (int i = 1;i <= n;i++){
     89         if (!vis[i]){
     90             dep[i]=1;
     91             dfs(i);
     92             f[i][0]=i;
     93             w[i][0]=inf;
     94         }
     95     }
     96     for (int i= 1;i <= 20;i++){
     97         for (int j = 1;j <= n;j++){
     98             f[j][i]=f[f[j][i-1]][i-1];
     99             w[j][i]=min(w[j][i-1],w[f[j][i-1]][i-1]);
    100         }
    101     }
    102     scanf ("%d",&q);
    103     for (int i = 1;i <= q;i++){
    104         scanf ("%d%d",&x,&y);
    105         printf("%d
    ",lca(x,y));
    106     }
    107     return 0;
    108 }

     另一道题UVA11354 Bond就是反过来,求最小生成树,LCA求最大值

  • 相关阅读:
    [J2ME Q&A]MMAPI的Cannot parse this type of AMR异常之讨论
    FM91.5的EasyMorning节目爱听吗?
    [EntLibFAQ]“不允许所请求的注册表访问权”的解释[0508Update]
    亮出你的组合竞争力的王牌
    隔离,隔离,再隔离!
    zuma三阶段论和技术道路[一]
    分享下我们部门内部知识点培训教程[SIP/J2ME/Setup/LoadRunner/Domino][0706Up]
    [Remoting FAQ]Loading a Remoting Host On IIS得到BadImageFormatException
    通过讲课来建立自己的知识系统
    j2medev“用户界面和多媒体”版面问题整理[0407更新]
  • 原文地址:https://www.cnblogs.com/very-beginning/p/13716759.html
Copyright © 2020-2023  润新知