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 }
弱者究竟为何而战?!