您的位置:首页 > 其它

【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)

2016-11-01 08:12 465 查看
【题意】

  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("\n");
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\n",ffind(x,y));
108         }
109     }
110     return 0;
111 }


View Code

2016-11-01 08:16:45
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: