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代码
  • 相关阅读:
    JAVAEE网上商城项目总结
    色盲小游戏
    jQuery(动画效果)
    Oracle exp,imp,expdp,impdp数据导入导出
    Sysbench压力测试工具简介和使用(二)
    Sysbench压力测试工具简介和使用(一)
    Eclipse常用快捷键汇总
    常用数据库连接URL地址大全
    H2数据库使用
    DbVisualizer 解决中文乱码问题
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9745789.html
Copyright © 2011-2022 走看看