zoukankan      html  css  js  c++  java
  • 【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)

    【题意】

      n个点m条边的图 q次询问 找到一条从s到t的一条边 使所有边的最大危险系数最小

    Input
    There will be at most 5 cases in the input file.
    The first line of each case contains two integers N, M (2 ≤ N ≤ 50000, 1 ≤ M ≤ 100000) – number
    of cities and roads. The next M lines describe the roads. The i-th of these lines contains three integers:
    xi, yi, di (1 ≤ xi, yi ≤ N, 0 ≤ di ≤ 10^9) – the numbers of the cities connected by the i-th road and its
    dangerousness.
    Description of the roads is followed by a line containing an integer Q (1 ≤ Q ≤ 50000), followed by
    Q lines, the i-th of which contains two integers si and ti (1 ≤ si
    , ti ≤ N, si ̸= ti).
    Consecutive input sets are separated by a blank line.
    Output
    For each case, output Q lines, the i-th of which contains the minimum dangerousness of a path between
    cities si and ti
    . Consecutive output blocks are separated by a blank line.
    The input file will be such that there will always be at least one valid path.
    Sample Input
    4 5
    1 2 10
    1 3 20
    1 4 100
    2 4 30
    3 4 10
    2
    1 4
    4 1
    2 1
    1 2 100
    1
    1 2
    Sample Output
    20
    20
    100

    【分析】

      很明显是最小瓶颈生成树。

      有一个定理:最小生成树是最小瓶颈生成树,但是最小瓶颈生成树不一定是最小生成树。

      我们只要求最小生成树就好了。

      不过这题n较大,不能n^2预处理,所以我们先把树求出来,然后询问的时候 树剖或者倍增 都可以。

      应该是,倍增耗空间但是时间少一个log , 树剖省一点空间但是 时间多一个log (要多一个数据结构维护)

      我上次就打一题倍增MLE了TAT,不过这题正解是倍增,不知道树剖+线段树能不能过。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 #define Maxn 50010
      9 #define Maxm 1000010
     10 #define INF 0xfffffff
     11 
     12 struct node
     13 {
     14     int x,y,c,next;
     15 }t[Maxn*2],tt[Maxm];
     16 int len;
     17 int first[Maxn];
     18 
     19 bool cmp(node x,node y) {return x.c<y.c;}
     20 int mymax(int x,int y) {return x>y?x:y;}
     21 
     22 int fa[Maxn];
     23 int ffind(int x)
     24 {
     25     if(fa[x]!=x) fa[x]=ffind(fa[x]);
     26     return fa[x];
     27 }
     28 
     29 void ins(int x,int y,int c)
     30 {
     31     t[++len].x=x;t[len].y=y;t[len].c=c;
     32     t[len].next=first[x];first[x]=len;
     33 }
     34 
     35 int f[Maxn][20],g[Maxn][20],dep[Maxn];
     36 
     37 void dfs(int x,int ff,int l)
     38 {
     39     dep[x]=dep[ff]+1;
     40     g[x][0]=ff;
     41     for(int i=1;(1<<i)<=dep[x];i++)
     42        g[x][i]=g[g[x][i-1]][i-1];
     43     f[x][0]=l;
     44     for(int i=1;(1<<i)<=dep[x];i++)
     45       f[x][i]=mymax(f[x][i-1],f[g[x][i-1]][i-1]);
     46     for(int i=first[x];i;i=t[i].next) if(t[i].y!=ff)
     47         dfs(t[i].y,x,t[i].c);
     48 }
     49 
     50 int ffind(int x,int y)
     51 {
     52     int ans=0;
     53     while(dep[x]!=dep[y])
     54     {
     55         int z;
     56         if(dep[x]<dep[y]) z=x,x=y,y=z;
     57         for(int i=18;i>=0;i--) if(dep[x]-(1<<i)>=dep[y])
     58             ans=mymax(ans,f[x][i]),x=g[x][i];
     59     }
     60     if(x==y) return ans;
     61     if(x!=y)
     62     {
     63         for(int i=18;i>=0;i--) if(g[x][i]!=g[y][i]&&dep[x]>=(1<<i))
     64             ans=mymax(ans,f[x][i]),ans=mymax(ans,f[y][i]),
     65             x=g[x][i],y=g[y][i];
     66     }
     67     ans=mymax(ans,f[x][0]);ans=mymax(ans,f[y][0]);
     68     return ans;
     69 }
     70 
     71 int main()
     72 {
     73     int n,m;
     74     bool ok=0;
     75     while(scanf("%d%d",&n,&m)!=EOF)
     76     {
     77         if(ok) printf("
    ");
     78         ok=1;
     79         for(int i=1;i<=m;i++)
     80         {
     81             scanf("%d%d%d",&tt[i].x,&tt[i].y,&tt[i].c);
     82         }
     83         sort(tt+1,tt+1+m,cmp);
     84         int cnt=0;
     85         for(int i=1;i<=n;i++) fa[i]=i;
     86         len=0;
     87         memset(first,0,sizeof(first));
     88         for(int i=1;i<=m;i++)
     89         {
     90             if(ffind(tt[i].x)!=ffind(tt[i].y))
     91             {
     92                 fa[ffind(tt[i].x)]=ffind(tt[i].y);
     93                 cnt++;
     94                 ins(tt[i].x,tt[i].y,tt[i].c);
     95                 ins(tt[i].y,tt[i].x,tt[i].c);
     96             }
     97             if(cnt==n-1) break;
     98         }
     99         dep[0]=0;
    100         dfs(1,0,0);
    101         int q;
    102         scanf("%d",&q);
    103         for(int i=1;i<=q;i++)
    104         {
    105             int x,y;
    106             scanf("%d%d",&x,&y);
    107             printf("%d
    ",ffind(x,y));
    108         }
    109     }
    110     return 0; 
    111 }
    View Code

    2016-11-01 08:16:45

  • 相关阅读:
    react 封装antd menu组件,路由懒加载,可折叠,可配置显示和隐藏,刷新后选择正确的菜单,打开正确的submenu
    useHistory做页面跳转导航
    react-draft-wysiwyg富文本组件
    html转json json转html
    create-react-app 生成 report.html 可视化打包分析
    axios设置请求头实现post请求发送数据的格式(Form Data)
    url查询参数中的汉字如何解码
    React在body下追加全局组件并实现渲染更新
    Loadrunner-08-增强和优化脚本-检查点
    Loadrunner-06-增强和优化脚本-事务
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6018155.html
Copyright © 2011-2022 走看看