【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

原文地址:https://www.cnblogs.com/Konjakmoyu/p/6018155.html