codevs 3287 货车运输 NOIP2013提高组

题目链接:http://codevs.cn/problem/3287/

题解:

  和bzoj3732一毛一样,只不过是找最大生成树和最小值罢了,具体参见我的bzoj3732的博客

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4 #define MAXN 100010
  5 #define MAXM 1000010
  6 int n,m,k,heade[MAXN],father[MAXN],fa[20][MAXN],dep[MAXN];
  7 struct edge1
  8 {
  9     int u,v,val;
 10 }e1[MAXM];
 11 struct edge
 12 {
 13     int v,next,val;
 14 }e[MAXM];
 15 int min(int x,int y)
 16 {
 17     return x<y?x:y;
 18 }
 19 int find(int x)
 20 {
 21     return father[x]=father[x]==x?x:find(father[x]);
 22 }
 23 bool cmp(edge1 a,edge1 b)
 24 {
 25     return a.val>b.val;
 26 }
 27 void adde(int i,int x,int y,int z)
 28 {
 29     e1[i]=(edge1){x,y,z};
 30 }
 31 void dfs(int u)
 32 {
 33     for(int i=heade[u];i;i=e[i].next)
 34     {
 35         if(!dep[e[i].v])
 36         {
 37             dep[e[i].v]=dep[u]+1;
 38             fa[0][e[i].v]=u;
 39             dfs(e[i].v);
 40         }
 41     }
 42 }
 43 int LCA(int u,int v)
 44 {
 45     if(dep[u]>dep[v])swap(u,v);
 46     for(int i=16;~i;i--)
 47         if(dep[fa[i][v]]>=dep[u])
 48             v=fa[i][v];
 49     if(u==v)return u;
 50     for(int i=16;~i;i--)
 51         if(fa[i][u]!=fa[i][v])
 52         {
 53             u=fa[i][u];
 54             v=fa[i][v];
 55         }
 56     return fa[0][u];
 57 }
 58 int main()
 59 {
 60     scanf("%d%d",&n,&m);
 61     int x,y,z;
 62     for(int i=1;i<=m;i++)
 63     {
 64         scanf("%d%d%d",&x,&y,&z);
 65         adde(i<<1,x,y,z);
 66         adde(i<<1+1,y,x,z);
 67     }
 68     for(int i=1;i<=n;i++)
 69         father[i]=i;
 70     sort(e1+1,e1+m*2+1,cmp);
 71     int cnt=0;
 72     for(int i=1;i<=m*2;i++)
 73     {
 74         x=find(e1[i].u);
 75         y=find(e1[i].v);
 76         if(x!=y)
 77         {
 78             int u=e1[i].u,v=e1[i].v;
 79             father[y]=x;
 80             ++cnt;
 81             e[cnt<<1]=(edge){v,heade[u],e1[i].val};
 82             heade[u]=cnt<<1;
 83             e[(cnt<<1)+1]=(edge){u,heade[v],e1[i].val};
 84             heade[v]=(cnt<<1)+1;
 85             if(cnt==n-1)break;
 86         }
 87     }
 88     dep[1]=fa[0][1]=1;
 89     dfs(1);
 90     for(int i=1;i<=16;i++)
 91         for(int j=1;j<=n;j++)
 92             fa[i][j]=fa[i-1][fa[i-1][j]];
 93     scanf("%d",&k);
 94     while(k--)
 95     {
 96         scanf("%d%d",&x,&y);
 97         int lca=LCA(x,y),t=x,ans=2147483647;
 98         if(!lca)
 99         {
100             printf("-1
");
101             continue;
102         }
103         while(t!=lca)
104         {
105             for(int i=heade[t];i;i=e[i].next)
106             {
107                 if(dep[e[i].v]<dep[t])
108                 {
109                     t=e[i].v;
110                     ans=min(ans,e[i].val);
111                     break;
112                 }
113             }
114         }
115         t=y;
116         while(t!=lca)
117         {
118             for(int i=heade[t];i;i=e[i].next)
119             {
120                 if(dep[e[i].v]<dep[t])
121                 {
122                     t=e[i].v;
123                     ans=min(ans,e[i].val);
124                     break;
125                 }
126             }
127         }
128         printf("%d
",ans);
129     }
130     return 0;
131 }
原文地址:https://www.cnblogs.com/xqmmcqs/p/5970590.html