当前位置 : 主页 > 手机开发 > harmonyos >

BOJ 292 MABODX

来源:互联网 收集:自由互联 发布时间:2023-10-08
MABODX Accept:17 Submit:88 Time Limit:4000MS Memory Limit:65536KB Description There is a country which has N city. Because The king spend littlemoney on the road ,so there is one and only one path from any cityto another city,every city has


MABODX


 

Accept:17 

  Submit:88

Time Limit:4000MS 

  Memory Limit:65536KB

Description

There is a country which has N city. Because The king spend littlemoney on the road ,so there is one and only one path from any cityto another city,every city has a apple tree.The apple in one citywhich has only one apple tree is the same.

Now The king wants to ask Bobo some questions .The king wants toknow if he walk from A city to B city and pick apples from the appletree when he pass one city (including A city and B city) what is thesum value of apples.But Bobo can't the question so he turns to yourhelp.


Input

There are many cases.

The first line of every case is N andM.N(1<=N<=50000) means N city, M(1<=M<=50000) means Mquestion .

Then N-1 line represent the roadbetween the country. Then the N line has N number the ith number onthe N line means the value of the apple in the ith city(the value isless than 10000) .

Then M line .Each line has 2 numberA(1<=A<=N) and B(1<=B<=N) ,means king ask if he walk fromcity A to city B.


Output

The sum value of appple of everyquestion. Output one line one answer.


Sample Input

3 2

1 2

1 3

5 7 10

1 3

3 2


Sample Output

15

22


Source

mabodx


此题用LCA做,首先预处理dfs求出每一点到根节点的权值,再LCA即可

#include<cstdio>
#include<string.h>
using namespace std;
int n,m,num[50100],sum[50100],ans[50100];
int head1[50100],head2[50100],cnt,f[50100],ff[50100];
bool flag[50100];
struct Edge{
    int f,v,id,next;
}edge[50100*7];
void addedge(int u,int v,int id,int *head){
    edge[cnt].f=u;
    edge[cnt].v=v;
    edge[cnt].id=id;
    edge[cnt].next=head[u];
    head[u]=cnt++;

    edge[cnt].f=v;
    edge[cnt].v=u;
    edge[cnt].id=id;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}
void dfs(int u,int father){
	int i;
	for(i=head1[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(v!=father){
			sum[v]=sum[u]+num[v];
            dfs(v,u);
        }
    }
}
int find(int u){
	int s;
	for(s=u;f[s]!=s;s=f[s]);
	while(s!=u){
		int tmp=f[u];
		f[u]=s;
		u=tmp;
	}
	return s;
}
void tarjan(int u,int father){
    int i;
    f[u]=u;
    for(i=head1[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(v!=father){
            tarjan(v,u);
            f[v]=u;
        }
    }
    flag[u]=1;
    for(i=head2[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(flag[v]){
			int t=find(v);
			ans[edge[i].id]=sum[edge[i].f]+sum[edge[i].v]-2*sum[t]+num[t];
        }
    }
}
int main(){
    int i,j;
    while(scanf("%d %d",&n,&m)==2){
        memset(head1,-1,sizeof(head1));
        memset(head2,-1,sizeof(head2));
        memset(flag,0,sizeof(flag));
		memset(ff,0,sizeof(ff));
        memset(sum,0,sizeof(sum));
        memset(f,0,sizeof(f));
        cnt=0;
        for(i=1;i<n;i++){
            int u,v;
            scanf("%d %d",&u,&v);
            addedge(u,v,0,head1);
        }
        for(i=1;i<=n;i++)
            scanf("%d",&num[i]);
        for(i=1;i<=m;i++){
            int u,v;
            scanf("%d %d",&u,&v);
            addedge(u,v,i,head2);
        }
		sum[1]=num[1];
		dfs(1,0);
        tarjan(1,0);
        for(i=1;i<=m;i++)
            printf("%d\n",ans[i]);
    }
}




打比赛时我一直用的带权值的并查集做,一直WA,现在也没查出错,望路过的大牛能够指正

#include<cstdio>
#include<string.h>
using namespace std;
int n,m,num[50100],sum[50100],ans[50100];
int head1[50100],head2[50100],head3[50100],cnt,f[50100],ff[50100];
bool vis[50100],flag[50100];
struct Edge{
    int f,v,id,next;
}edge[50100*7];
void addedge(int u,int v,int id,int *head){
    edge[cnt].f=u;
    edge[cnt].v=v;
    edge[cnt].id=id;
    edge[cnt].next=head[u];
    head[u]=cnt++;

    edge[cnt].f=v;
    edge[cnt].v=u;
    edge[cnt].id=id;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}
int find(int u){
    if(f[u]==u){
        sum[u]=num[u];
        return u;
    }
    f[u]=find(f[u]);
    sum[u]=sum[ff[u]]+num[u];
    return f[u];
}
void tarjan(int u){
    int i;
    f[u]=u;
    for(i=head1[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(!vis[v] ){
            vis[v]=1;
            tarjan(v);
            f[v]=u;
	    ff[v]=u;
	    find(v);
        }
    }
    flag[u]=1;
    for(i=head2[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        if(flag[v]){
			int t=find(v);
            edge[cnt].v=i;
            edge[cnt].next=head3[t];
            head3[t]=cnt++;
        }
    }
    for(i=head3[u];i!=-1;i=edge[i].next){
        int j=edge[i].v;
        int uu=edge[j].f;
        int vv=edge[j].v;
        int id=edge[j].id;
        find(uu);
        ans[id]=sum[uu]+sum[vv]-num[u];
    }
}
int main(){
    int i,j;
    while(scanf("%d %d",&n,&m)==2){
        memset(head1,-1,sizeof(head1));
        memset(head2,-1,sizeof(head2));
        memset(head3,-1,sizeof(head3));
        memset(vis,0,sizeof(vis));
        memset(flag,0,sizeof(flag));
	memset(ff,0,sizeof(ff));
        memset(sum,0,sizeof(sum));
        memset(f,0,sizeof(f));
        cnt=0;
        for(i=1;i<n;i++){
            int u,v;
            scanf("%d %d",&u,&v);
            addedge(u,v,0,head1);
        }
        for(i=1;i<=n;i++)
            scanf("%d",&num[i]);
        for(i=1;i<=m;i++){
            int u,v;
            scanf("%d %d",&u,&v);
            addedge(u,v,i,head2);
        }
        vis[1]=1;
        tarjan(1);
        for(i=1;i<=m;i++)
            printf("%d\n",ans[i]);
    }
}

 

 

 

 

上一篇:POJ 3349 Snowflake Snow Snowflakes
下一篇:没有了
网友评论