bzoj 3732Network

先搞个最小生成树,然后lca(和之前的一个cf题差不多2333, 纯属颓废了。。)

顺便思考了一下正确性。

因为所求的是所有路径中最大边的最小值。而kruskal每次往里添加的就是最小边。所以在生成树之后两点之间的路径,都是严格按最小的插入的,所以里面的最大边会最小。(貌似说了些废话,,,)

 1 #include<bits/stdc++.h>
 2 #define inf 0x7fffffff
 3 #define LL long long
 4 #define N 100005
 5 using namespace std;
 6 inline int ra()
 7 {
 8     int x=0,f=1; char ch=getchar();
 9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
11     return x*f;
12 }
13 struct node{
14     int to,next,v;
15 }e[N<<1];
16 struct data{
17     int x,y,v;
18 }a[N];
19 int n,m,k;
20 int head[N],cnt,deep[N],father[N],f[N][20],mx[N][20]; 
21 void insert(int x, int y, int v)
22 {
23     e[++cnt].to=y;
24     e[cnt].next=head[x];
25     e[cnt].v=v;
26     head[x]=cnt;
27 }
28 int find(int x){return father[x]==x?x:father[x]=find(father[x]);}
29 bool cmp(data a, data b){return a.v<b.v;}
30 void dfs(int x, int fa)
31 {
32     for (int i=1; i<=18; i++)
33     {
34         f[x][i]=f[f[x][i-1]][i-1];
35         mx[x][i]=max(mx[x][i-1],mx[f[x][i-1]][i-1]);
36     }
37     for (int i=head[x];i;i=e[i].next)
38     {
39         if (e[i].to==fa) continue;
40         f[e[i].to][0]=x;
41         mx[e[i].to][0]=e[i].v;
42         deep[e[i].to]=deep[x]+1;
43         dfs(e[i].to,x);
44     }
45 }
46 int getans(int x, int y)
47 {
48     int ans=0;
49     if (deep[x]<deep[y]) swap(x,y);
50     int t=deep[x]-deep[y];
51     for (int i=0; i<=18; i++) 
52         if (t&(1<<i)) ans=max(ans,mx[x][i]),x=f[x][i];
53     for (int i=18; i>=0; i--)
54         if (f[x][i]!=f[y][i])
55         {
56             ans=max(ans,max(mx[x][i],mx[y][i]));
57             x=f[x][i]; y=f[y][i];
58         }
59     if (x!=y) return max(ans,max(mx[x][0],mx[y][0]));
60     return ans;
61 }
62 int main()
63 {
64     n=ra(); m=ra(); k=ra();
65     for (int i=1; i<=m; i++)
66         a[i].x=ra(),a[i].y=ra(),a[i].v=ra();
67     sort(a+1,a+m+1,cmp);
68     for (int i=1; i<=n; i++) father[i]=i;
69     int tot=0;
70     for (int i=1; i<=m; i++)
71     {
72         int p=find(a[i].x),q=find(a[i].y);
73         if (q!=p)
74             father[q]=p,tot++,insert(a[i].x,a[i].y,a[i].v),insert(a[i].y,a[i].x,a[i].v);
75         if (tot==n-1) break;
76     }
77     dfs(1,0);
78     for (int i=1; i<=k; i++)
79     {
80         int x=ra(),y=ra();
81         printf("%d\n",getans(x,y));
82     }
83     return 0;
84 }

 

posted @ 2017-02-10 10:03  ws_ccd  阅读(117)  评论(0编辑  收藏  举报