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

    读完题,我产生了一个显然的想法:先求出这张图的最大生成树,然后再dfs一遍求出联通块的个数(图可能不连通),之后这张图变成了一棵树,题目就变成了在一棵树上给定一条路径,求这条路径上最小的边权是多少。(-1的情况可以通过并查集直接判断)。

    考虑一条路路径(x,y),我们可以把它拆分成(x,lca(x,y))和(lca(x,y),y)两条路径,我们可以通过倍增实现lca,在预处理时维护两个数组,fa[x][i]表示x的2i辈祖先是谁,minn[x][i]表示在路径(x,fa[x][i])中最小的边权。minn数组的求法有一点类似ST表。

    有了这些,我们就可以解决问题了。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 inline int read() {
      7     int ret=0;
      8     int op=1;
      9     char c=getchar();
     10     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
     11     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
     12     return ret*op;
     13 }
     14 struct node {
     15     int from,to,dis;
     16     bool operator <(const node &x) const {
     17         return dis>x.dis;
     18     }
     19 }a[50010];
     20 struct Edge {
     21     int next,to,dis;
     22 }edge[50010<<1];
     23 int head[50010<<1],num,fa[10010][19],minn[10010][19],f[10010],d[10010],tot,vis[10010];
     24 int n,m;
     25 int find(int x) {
     26     if(f[x]!=x) f[x]=find(f[x]);
     27     return f[x];
     28 }
     29 inline void add(int from,int to,int dis) {
     30     edge[++num].next=head[from]; edge[num].to=to; edge[num].dis=dis; head[from]=num;
     31     swap(from,to);
     32     edge[++num].next=head[from]; edge[num].to=to; edge[num].dis=dis; head[from]=num;
     33 }
     34 void dfs(int u) {
     35     vis[u]=1;
     36     for(int i=head[u];i;i=edge[i].next) {
     37         int v=edge[i].to;
     38         if(!vis[v]) {
     39             d[v]=d[u]+1;
     40             fa[v][0]=u;
     41             minn[v][0]=edge[i].dis;
     42             dfs(v);
     43         }
     44     }
     45 }
     46 int lca(int x,int y) {
     47     int ans=2147483647;
     48     if(d[x]<d[y]) swap(x,y);
     49     for(int i=17;i>=0;i--)
     50         if(d[fa[x][i]]>=d[y]) {
     51             ans=min(ans,minn[x][i]);
     52             x=fa[x][i];
     53         }
     54     if(x==y) return ans;
     55     for(int i=17;i>=0;i--)
     56         if(fa[x][i]!=fa[y][i]) {
     57             ans=min(ans,min(minn[x][i],minn[y][i]));
     58             x=fa[x][i];
     59             y=fa[y][i];
     60         }
     61     return ans=min(ans,min(minn[x][0],minn[y][0]));
     62 }
     63 int main() {
     64     n=read(); m=read();
     65     for(int i=1;i<=m;i++) {
     66         a[i].from=read();
     67         a[i].to=read();
     68         a[i].dis=read();
     69     }
     70     sort(a+1,a+m+1);
     71     for(int i=1;i<=n;i++) f[i]=i;
     72     for(int i=1;i<=m;i++) {
     73         if(tot==n-1) break ;
     74         if(find(a[i].from)!=find(a[i].to)) {
     75             tot++;
     76             add(a[i].from,a[i].to,a[i].dis);
     77             f[find(a[i].from)]=f[find(a[i].to)];
     78         }
     79     }
     80     memset(vis,0,sizeof(vis));
     81     for(int i=1;i<=n;i++) 
     82         if(!vis[i]) {
     83             d[i]=1;
     84             dfs(i);
     85             fa[i][0]=i;
     86             minn[i][0]=999999999;
     87         }
     88     for(int j=1;j<=17;j++)
     89         for(int i=1;i<=n;i++) {
     90             fa[i][j]=fa[fa[i][j-1]][j-1];
     91             minn[i][j]=min(minn[i][j-1],minn[fa[i][j-1]][j-1]);
     92         }
     93     int op=read();
     94     while(op--) {
     95         int x=read(),y=read();
     96         if(find(x)!=find(y)) puts("-1");
     97         else printf("%d
    ",lca(x,y));
     98     }
     99     return 0;
    100 }
    AC Code
  • 相关阅读:
    如何使用shell脚本快速排序和去重文件数据
    centos7下搭建git和gitlab版本库
    Jenkins安装部署
    那日了狗的上半年的兼容性问题,下半年来解决。
    RecyclerView notifyDataSetChanged不起作用
    android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法
    java.lang.UnsatisfiedLinkError: Couldn't load hyphenate_av from loader dalvik.system.PathClassLoader
    android studio Error:java.lang.OutOfMemoryError: GC overhead limit exceeded
    apache https配置
    docker进入容器的方式
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10802431.html
Copyright © 2011-2022 走看看