ZOJ3195 Design the city LCA

    求三个点之间距离和的最小值,画个图想想就可以知道这个值就是两两距离之和除以2

   两组数据 之间 要有一个换行  这里PE了很多次

    

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 100005;
 6 struct edge
 7 {
 8     int v,w,next;
 9 }e[maxn];
10 struct node
11 {
12     int v,next,ans;
13 }q[maxn*5];
14 int cnt,cnt_a,head1[maxn],head2[maxn],vis[maxn],vis1[maxn],fa[maxn],d[maxn];
15 void init(int n)
16 {
17     cnt = 0;cnt_a = 0;
18     memset(head1,-1,sizeof(head1));
19     memset(head2,-1,sizeof(head2));
20     memset(vis,0,sizeof(vis));
21     memset(vis1,0,sizeof(vis1));
22     for(int i = 0;i<n;++i)fa[i] = i;
23 }
24 int findd(int x)
25 {
26     int ret = x;
27     while(ret!=fa[ret])ret = fa[ret];
28     while(x!=ret)
29     {
30 
31         int t = fa[x];
32         fa[x] = ret;
33         x = t;
34     }
35     return ret;
36 }
37 void lca(int rt)
38 {
39     vis[rt] = 1;
40     for(int i = head1[rt];i!=-1;i=e[i].next)if(!vis[e[i].v])
41     {
42         d[e[i].v] = d[rt]+e[i].w;
43         lca(e[i].v);
44         fa[e[i].v] = rt;
45     }
46     vis1[rt] = 1;
47     for(int i = head2[rt];i!=-1;i = q[i].next)if(vis1[q[i].v])
48         q[i].ans = q[i^1].ans = d[rt]+d[q[i].v]-2*d[findd(q[i].v)];
49 }
50 void add(int u,int v,int w)
51 {
52     e[cnt].v=v;e[cnt].w=w;
53     e[cnt].next = head1[u];
54     head1[u]=cnt++;
55 }
56 void add_a(int u,int v)
57 {
58     q[cnt_a].v = v;
59     q[cnt_a].next = head2[u];
60     head2[u] = cnt_a++;
61 }
62 int main()
63 {
64 //    freopen("in.txt","r",stdin);
65     int n,m;
66     int first = 1;
67     while(~scanf("%d",&n))
68     {
69         init(n);
70         for(int i = 1;i<n;++i)
71         {
72             int x,y,z;scanf("%d%d%d",&x,&y,&z);
73             add(x,y,z);
74             add(y,x,z);
75         }
76         scanf("%d",&m);
77         for(int i = 1;i<=m;++i)
78         {
79             int x,y,z;scanf("%d%d%d",&x,&y,&z);
80             add_a(x,y);add_a(y,x);
81             add_a(x,z);add_a(z,x);
82             add_a(z,y);add_a(y,z);
83         }
84         lca(0);
85         if(!first)printf("\n");first = 0;
86         for(int i = 0;i<cnt_a;i+=6)
87             printf("%d\n",(q[i].ans+q[i+2].ans+q[i+4].ans)/2);
88 
89     }
90     return 0;
91 }

 

posted on 2015-05-07 17:19  round_0  阅读(149)  评论(0编辑  收藏  举报

导航