水题 求出三个人每两个间的LCA,然后最小花费就是两两点之间的路径长度之和除以2
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 500005; 6 struct edge{ 7 int v,next; 8 }e[maxn*2]; 9 struct ask{ 10 int v,next,lca,d,u; 11 }q[maxn*6]; 12 int head[maxn],cnt,head1[maxn],cnt_ask; 13 int d[maxn],fa[maxn],vis[maxn]; 14 void init() 15 { 16 memset(head,-1,sizeof(head)); 17 memset(head1,-1,sizeof(head1)); 18 memset(vis,0,sizeof(vis)); 19 cnt = cnt_ask = d[1] = 0; 20 } 21 void add(int u,int v) 22 { 23 e[cnt].v = v; 24 e[cnt].next = head[u]; 25 head[u] = cnt++; 26 } 27 void add_ask(int u,int v) 28 { 29 q[cnt_ask].v = v; 30 q[cnt_ask].u = u; 31 q[cnt_ask].next = head1[u]; 32 head1[u] = cnt_ask++; 33 } 34 void dfs(int rt,int father) 35 { 36 for(int i = head[rt];i!=-1;i=e[i].next)if(e[i].v!=father) 37 { 38 d[e[i].v] = d[rt]+1; 39 dfs(e[i].v,rt); 40 } 41 } 42 int findd(int x) 43 { 44 int rt = x; 45 while(rt!=fa[rt])rt = fa[rt]; 46 while(x!=rt){ 47 int t = fa[x]; 48 fa[x] = rt; 49 x = t; 50 } 51 return rt; 52 } 53 void lca(int rt,int father){ 54 fa[rt] = rt; 55 for(int i = head[rt];i!=-1;i=e[i].next)if(father!=e[i].v){ 56 lca(e[i].v,rt); 57 fa[e[i].v] = rt; 58 } 59 vis[rt] = 1; 60 for(int i = head1[rt];i!=-1;i=q[i].next)if(vis[q[i].v]){ 61 q[i].lca = q[i^1].lca = findd(q[i].v); 62 } 63 } 64 int main() 65 { 66 //freopen("in.txt","r",stdin); 67 int n,m;scanf("%d%d",&n,&m); 68 init(); 69 for(int i = 1;i<n;++i){ 70 int u,v;scanf("%d%d",&u,&v); 71 add(u,v);add(v,u); 72 } 73 dfs(1,1); 74 for(int i = 1;i<=m;++i){ 75 int u,v,w;scanf("%d%d%d",&u,&v,&w); 76 add_ask(u,v);add_ask(v,u); 77 add_ask(u,w);add_ask(w,u); 78 add_ask(w,v);add_ask(v,w); 79 } 80 lca(1,1); 81 for(int i = 0;i<cnt_ask;++i)q[i].d = d[q[i].u]+d[q[i].v]-2*d[q[i].lca]; 82 for(int i = 0;i<cnt_ask;i+=6){ 83 int ans1,ans2 = (q[i].d+q[i+2].d+q[i+4].d)/2; 84 ans1 = max(d[q[i].lca],max(d[q[i+2].lca],d[q[i+4].lca])); 85 for(int j = i;j<i+5;j+=2) 86 if(ans1==d[q[j].lca]){ 87 ans1 = q[j].lca;break; 88 } 89 printf("%d %d\n",ans1,ans2); 90 } 91 return 0; 92 }
时间: 2024-10-10 15:16:30