P1967 货车运输

P1967 货车运输
最大生成树+lca+并查集

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<queue>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<ctime>
  7 #include<set>
  8 #include<map>
  9 #include<stack>
 10 #include<cstring>
 11 #define inf 2147483647
 12 #define For(i,a,b) for(register int i=a;i<=b;i++)
 13 #define p(a) putchar(a)
 14 #define g() getchar()
 15 //by war
 16 //2017.11.8
 17 using namespace std;
 18 int n,m,q;
 19 int x,y,z;
 20 int cnt;
 21 int Min[10010][15];
 22 int f[10010][15];
 23 int d[10010];
 24 int deep[10010];
 25 
 26 struct kru
 27 {
 28     int l,r,v;
 29     bool operator<(const kru&a)const
 30     {
 31         return v>a.v;
 32     }
 33 }E[50010];
 34 
 35 struct node
 36 {
 37     int n;
 38     int v;
 39     node *next;
 40 }*e[50010];
 41 
 42 inline void in(register int &x)
 43 {
 44     int y=1;
 45     char c=g();x=0;
 46     while(c<'0'||c>'9')
 47     {
 48     if(c=='-')
 49     y=-1;
 50     c=g();
 51     }
 52     while(c<='9'&&c>='0')x=(x<<1)+(x<<3)+c-'0',c=g();
 53     x*=y;
 54 }
 55 inline void o(register int x)
 56 {
 57     if(x<0)
 58     {
 59         p('-');
 60         x=-x;
 61     }
 62     if(x>9)o(x/10);
 63     p(x%10+'0');
 64 }
 65 
 66 inline int find(register int x)
 67 {
 68     if(d[x]==x)return x;
 69     d[x]=find(d[x]);
 70     return d[x];
 71 }
 72 
 73 inline void push(register int x,register int y,register int v)
 74 {
 75     node *p;
 76     p=new node();
 77     p->n=y;
 78     p->v=v;
 79     if(e[x]==NULL)
 80     e[x]=p;
 81     else
 82     {
 83         p->next=e[x]->next;
 84         e[x]->next=p;
 85     }
 86 }
 87 
 88 inline void build(register int now)
 89 {
 90     deep[now]=deep[f[now][0]]+1;
 91     for(register int i=1;(1<<i)<=n;i++)
 92     {
 93         Min[now][i]=min(Min[now][i-1],Min[f[now][i-1]][i-1]);
 94         f[now][i]=f[f[now][i-1]][i-1];
 95     }
 96     for(node *i=e[now];i!=NULL;i=i->next)
 97     {
 98         if(i->n!=f[now][0])
 99         {
100             f[i->n][0]=now;
101             Min[i->n][0]=i->v;
102             build(i->n);
103         }
104     }
105 }
106 
107 int query(int x,int y)
108 {
109     int MIN=inf;
110     if(deep[x]<deep[y])
111     swap(x,y);
112     int c=deep[x]-deep[y];
113     for(register int i=0;(1<<i)<=c;i++)
114     if((1<<i)&c)
115     {
116     MIN=min(MIN,Min[x][i]);
117     x=f[x][i];    
118     }
119     if(x==y)
120     return MIN;
121     c=log2(deep[x]);
122     for(register int i=c;i>=0;i--)
123     {
124         if(f[x][i]!=f[y][i])
125         {
126             MIN=min(MIN,Min[x][i]);
127             MIN=min(MIN,Min[y][i]);
128             x=f[x][i];
129             y=f[y][i];
130         }
131     }
132     return min(MIN,min(Min[y][0],Min[x][0]));
133 }
134 
135 int main()
136 {
137     in(n),in(m);
138     For(i,1,n)
139     d[i]=i;
140     For(i,1,m)
141     in(E[i].l),in(E[i].r),in(E[i].v);
142     sort(E+1,E+m+1);
143     For(i,1,m)
144     {
145         if(find(E[i].l)!=find(E[i].r))
146         {
147             d[find(E[i].l)]=find(E[i].r);
148             cnt++;
149             push(E[i].l,E[i].r,E[i].v);
150             push(E[i].r,E[i].l,E[i].v);
151         }
152         if(cnt==n-1)
153         break;
154     }
155     Min[1][0]=inf;
156     build(1);
157     in(q);
158     For(i,1,q)
159     {
160         in(x),in(y);
161         if(find(x)!=find(y))
162         o(-1),p('\n');
163         else
164         o(query(x,y)),p('\n');
165     }
166      return 0;
167 }

 

posted @ 2017-11-09 08:20  WeiAR  阅读(213)  评论(0编辑  收藏  举报