P1967 货车运输 未完成

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 using namespace std;
  7 const int MAXN=50001;
  8 int n,m;
  9 int x,y,z;
 10 struct node
 11 {
 12     int u,v,w,next;
 13 }edge[MAXN],a[MAXN];
 14 int num=1;
 15 int head[MAXN];
 16 int f[MAXN];
 17 int anum=1;
 18 int ahead[MAXN];
 19 int deep[MAXN];
 20 int s[MAXN][20];
 21 int take[MAXN][20];
 22 void edge_add(int x,int y,int z)
 23 {
 24     edge[num].u=x;
 25     edge[num].v=y;
 26     edge[num].w=z;
 27     edge[num].next=head[x];
 28     head[x]=num++;
 29 }
 30 void a_add(int i)
 31 {
 32     a[anum].u=edge[i].u;
 33     a[anum].v=edge[i].v;
 34     a[anum].w=edge[i].w;
 35     a[anum].next=ahead[a[anum].u];
 36     ahead[a[anum].u]=anum++;
 37 }
 38 int comp(const node & a ,const node & b)
 39 {return a.w>b.w;}
 40 
 41 int find(int x)
 42 {
 43     if(f[x]!=x)
 44     f[x]=find(f[x]);
 45     return f[x];
 46 }
 47 void unionn(int x,int y)
 48 {
 49     int fx=find(x);
 50     int fy=find(y);
 51     f[fx]=fy;
 52 }
 53 void Biggest_Kruskal()
 54 {
 55     sort(edge+1,edge+num,comp);
 56     int k=0;
 57     for(int i=1;i<num;i++)
 58     {
 59         int uu=edge[i].u;
 60         int vv=edge[i].v;
 61         if(find(uu)!=find(vv))
 62         {
 63             unionn(uu,vv);
 64             a_add(i);
 65             k++;
 66         }
 67         if(k==n-1)break;
 68     }
 69     for(int i=1;i<=anum;i++)
 70         cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].w<<" "<<a[i].next<<endl;
 71 }
 72 void Build_Tree(int p)
 73 {
 74     for(int i=ahead[p];i!=-1;i=a[i].next)
 75     {
 76         int will=a[i].v;
 77         if(deep[will]==0)
 78         {
 79             deep[will]=deep[p]+1;
 80             s[will][0]=p;
 81             take[will][0]=a[i].w;
 82             Build_Tree(will);
 83         }
 84     }
 85 }
 86 void Initialize_Step()
 87 {
 88     for(int i=1;i<=19;i++)
 89     {
 90         for(int j=1;j<=n;j++)
 91         {
 92             s[j][i]=s[s[j][i-1]][i-1];
 93             take[j][i]=min(take[j][i-1],take[s[j][i-1]][i-1]);
 94         }
 95     }
 96 }
 97 int LCA(int x,int y)
 98 {
 99     int ans=0x7ff;
100     if(deep[x]<deep[y])
101     swap(x,y);
102     for(int i=19;i>=0;i--)
103     {
104         if(deep[s[x][i]]>=deep[y])
105         x=s[x][i];
106     }
107     if(x==y)
108     return x;
109     for(int i=19;i>=0;i--)
110     {
111         if(s[x][i]!=s[y][i])
112         {
113             x=s[x][i];
114             y=s[y][i];
115             ans=min(ans,take[x][i]);
116             ans=min(ans,take[y][i]);
117         }
118     }
119     ans=min(ans,take[x][0]);
120     ans=min(ans,take[y][0]);
121     return ans;
122 }
123 int main()
124 {
125     scanf("%d%d",&n,&m);
126     
127     for(int i=1;i<=n;i++)
128     {head[i]=-1;f[i]=i;ahead[i]=-1;}
129     
130     for(int i=1;i<=m;i++)
131     {
132         scanf("%d%d%d",&x,&y,&z);
133         edge_add(x,y,z);
134         //edge_add(y,x,z);
135     }
136     Biggest_Kruskal();
137     deep[1]=1;
138     for(int i=1;i<=n;i++)
139     Build_Tree(i);
140     Initialize_Step();
141     int q;
142     scanf("%d",&q);
143     for(int i=1;i<=q;i++)
144     {
145         int x,y;
146         scanf("%d%d",&x,&y);
147         if(find(x)!=find(y))
148         {
149             printf("-1\n");
150             continue;
151         }
152         printf("%d\n",LCA(x,y));
153     }
154     return 0;
155 } 

 

posted @ 2017-05-09 21:40  自为风月马前卒  阅读(137)  评论(0编辑  收藏  举报

Contact with me