HDU 3078 Network LCA .

来源:互联网 发布:网络大电影盈利案例 编辑:程序博客网 时间:2024/05/14 07:28
题意:n个点 m个询问,下面一行是n 个点的权值 再下面n-1行是双向的边<p>然后m个询问:k u v 若k==0,则把u点的权值改为v,否则回答u->v之间最短路经过点的权值中  第k大的值是多少</p><p>ac代码(注意 数组要开大点 80000是不够的 我开了160000):</p><pre class="cpp" name="code">#include<stdio.h>#include<string.h>#define MAX 160100struct node{int to,from;}node[MAX];struct tree{int mer,deep;}tree[MAX];int s[MAX],mark[MAX],head[MAX],cnt,x,t[MAX];void add(int q,int z){node[cnt].to=z;node[cnt].from=head[q];head[q]=cnt++;}void bulid(int mer,int deep){for(int k=head[mer];k+1;k=node[k].from){int to=node[k].to;if(mark[to]);else{mark[to]=1;tree[to].deep=deep+1;tree[to].mer=mer;bulid(to,deep+1);}}}void LCA(int a,int b){int y=1;x=0;while(tree[a].deep>tree[b].deep){t[y]=s[a];a=tree[a].mer;x++;y++;}while(tree[b].deep>tree[a].deep){t[y]=s[b];b=tree[b].mer;x++;y++;}while(a!=b){t[y]=s[a];y++;t[y]=s[b];y++;a=tree[a].mer;b=tree[b].mer;x+=2;}t[y]=s[a];x++;}int main(){int n,m,i,q,z,j,k,qwer,v,c;scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&s[i]);cnt=2;memset(mark,0,sizeof(mark));memset(head,-1,sizeof(head));for(i=1;i<n;i++){scanf("%d %d",&c,&v);add(c,v);add(v,c);mark[v]=1;}for(i=1;i<=n;i++){if(mark[i]==0){j=i;break;}}memset(mark,0,sizeof(mark));bulid(j,0);for(i=1;i<=m;i++){scanf("%d%d%d",&k,&q,&z);if(k==0)s[q]=z;else{x=0;LCA(q,z);//printf("x=%d\n",x);if(x<k)printf("invalid request!\n");else{int r=x;while(r--){for(q=1;q<x;q++){if(t[q]<t[q+1]){qwer=t[q];t[q]=t[q+1];t[q+1]=qwer;}}}//printf("\n\n");printf("%d\n",t[k]);/*printf("\n\nk=%d\n",k);for(j=1;j<=x;j++)printf("%d\n",s[t[j]]);printf("\n\n");*/memset(t,0,sizeof(t));}}}return 0;}
给两组数据吧 
8 99 5 2 3 4 5 6 7 8 1 3 1 2 3 4  3 5  5 6 5 7 7 8 1 2 8 2 2 8 3 2 8 4 2 8 5 2 8 6 2 8 7 2 8 1 4 8 4 2 3 5 3 8 2 3 8 0 3 8 2 3 8 3 3 8 2 4 5 1 4 1 2 4 1 3 4 1  ans: 8 7 5 5 3 2 in... 8 in... in... 7 8 7 5 8 5 4  //// 1 1 5 1 1 1  ans: 5 
第一次写  写的不好  见谅!
                                             
0 0