zoukankan      html  css  js  c++  java
  • 【NOIP2013】货车运输

    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1967


    好坑啊!算了,还是怪我LCA写的不熟,沙茶一般把j<maxb写成(1<<j)<maxb。。。

    首先,我们可以生成一下最大生成树,保证每个点都连通的情况下,每条路的限重尽量大。但是注意点并不一定都连通,因此我们需要建立多棵最大生成树。然后我们的任务就是查询两点间路径上的最小边权,暴力的话复杂度难以接受,这是我们就可以使用一种较好的方法——倍增。说白了,就是在求LCA的同时维护路径上的最小边权。初始化时,mine[i][0]=w[i][fan[i][0]];然后有mine[i][j]=min(mine[i][j-1],mine[fan[i][j-1]][j-1])。再就是建树的过程容易出错,应该注意。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 inline int min(int a,int b) {return a<b?a:b;}
     7 inline void swap(int& a,int& b) {int t=a;a=b;b=t;}
     8 inline int get_num() {
     9     int num;char c;
    10     while((c=getchar())=='
    '||c==' '||c=='
    ');
    11     num=c-'0';
    12     while(isdigit(c=getchar())) num=num*10+c-'0';
    13     return num;
    14 }
    15 void put_num(int i) {
    16     if(i<0) putchar('-'),i=-i;
    17     if(i>9) put_num(i/10);
    18     putchar(i%10+'0');
    19 }
    20 const int maxn=1e4+5,maxm=5e4+5,maxb=15,inf=0x3f3f3f3f;
    21 struct Edge {
    22     int u,v,w;
    23     bool operator < (const Edge& rhs) const {
    24         return w>rhs.w;
    25     }
    26 } edge[maxm];
    27 int fa[maxn],d[maxn],fan[maxn][maxb],mine[maxn][maxb];
    28 int f(int i) {
    29     if(i==fa[i]) return i;
    30     else return fa[i]=f(fa[i]);
    31 }
    32 int dfs(int v) {
    33     if(d[v]) return d[v];
    34     if(f(v)) return d[v]=dfs(fan[v][0])+1;
    35     else return 1;
    36 }
    37 int query(int x,int y) {
    38     if(d[x]<d[y]) swap(x,y);
    39     int i,j,mmin=inf;
    40     for(i=0;(1<<i)<=d[x];++i);
    41     --i;
    42     for(j=i;j>=0;--j)
    43         if(d[x]-(1<<j)>=d[y])
    44             mmin=min(mmin,mine[x][j]),x=fan[x][j];
    45     if(x==y) return mmin;
    46     for(j=i;j>=0;--j)
    47         if(fan[x][j]!=fan[y][j]) {
    48             mmin=min(mmin,min(mine[x][j],mine[y][j]));
    49             x=fan[x][j],y=fan[y][j];
    50         }
    51     return min(mmin,min(mine[x][0],mine[y][0]));
    52 }
    53 int main() {
    54     int n,m,x,y,z,cnt=0;
    55     n=get_num();m=get_num();
    56     for(int i=1;i<=m;++i) {
    57         x=get_num();y=get_num();z=get_num();
    58         edge[i].u=x,edge[i].v=y,edge[i].w=z;
    59     }
    60     sort(edge+1,edge+m+1);
    61     for(int i=1;i<=n;++i) fa[i]=i;
    62     memset(mine,inf,sizeof(mine));
    63     for(int i=1;i<=m&&cnt<n-1;++i) {
    64         int u=f(edge[i].u),v=f(edge[i].v),w=edge[i].w;
    65         if(u!=v) fa[v]=u,fan[v][0]=u,mine[v][0]=w,++cnt;
    66     }
    67     for(int i=1;i<=n;++i) {
    68         int root=f(i);
    69         d[root]=1;
    70         if(!d[i]) dfs(i);
    71     }
    72     for(int j=1;j<maxb;++j)
    73         for(int i=1;i<=n;++i) {
    74             fan[i][j]=fan[fan[i][j-1]][j-1];
    75             mine[i][j]=min(mine[i][j-1],mine[fan[i][j-1]][j-1]);
    76         }
    77     int q=get_num(),first=1;
    78     for(int i=1;i<=q;++i) {
    79         x=get_num();y=get_num();
    80         if(first) first=0;
    81         else putchar('
    ');
    82         if(f(x)!=f(y)) put_num(-1);
    83         else put_num(query(x,y));
    84     }
    85     return 0;
    86 }
    AC代码
  • 相关阅读:
    Linnia学习记录
    漫漫考研路
    ENS的学习记录
    KnockoutJS 3.X API 第四章 数据绑定(4) 控制流with绑定
    KnockoutJS 3.X API 第四章 数据绑定(3) 控制流if绑定和ifnot绑定
    KnockoutJS 3.X API 第四章 数据绑定(2) 控制流foreach绑定
    KnockoutJS 3.X API 第四章 数据绑定(1) 文本及样式绑定
    KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册
    KnockoutJS 3.X API 第三章 计算监控属性(4)Pure computed observables
    KnockoutJS 3.X API 第三章 计算监控属性(3) KO如何实现依赖追踪
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9745789.html
Copyright © 2011-2022 走看看