4971:Gift

描述

 

趁着周末,小T约各位小伙伴们去露天烧烤,为了给小伙伴们一些惊喜,小A提前在沿途站点中准备了一些小礼物。已知地图上站点的总个数为N,从1~N编号,目的地编号为1,共有M位小伙伴应邀而来,那么问题来了,如果小伙伴们直接向目的地行进(一共N-1条路径连接N个站点,保证每个小伙伴去目的地的道路只有一条),他们一共可以收集到多少份小礼物呢?

 

输入

 

多组输入数据。每组数据之间存在一个空行。

每组输入第一行包含两个正整数N、M(1<=M,N<=1000),分别代表站点总个数和小伙伴人数。第二行包含M个正整数,Ai代表第i个小伙伴所在的站点编号。第三行包含N个正整数,Bi代表站点i放有小礼物的个数(0<=Bi<=1000)。接下来包含N-1行,每行两个正整数u和v,代表站点u和v之间存在一条道路。

数据保证所有站点都直接或间接的连通,即从任意一站点出发,都可以到达其他任意站点。

 

 

输出

 

对于每组数据输出一个整数,代表小伙伴们一共能够收集到的小礼物个数。具体格式见样例。

 

样例输入

 

样例输出

 

提示

注意:礼物被第一个人拿走后,第二个人到达站点时就不会获得礼物。

又是我爱的深搜 like

#include<bits/stdc++.h>
using namespace std;
int n,m,f,v[1005],a[1005],vis[1005],sum;
vector<int>mp[1005];
void dfs(int u)
{
    int i;
    if(u==1||f==1)
    {
        f=1;
        return ;
    }
    vis[u]=1;
    for(i=0;i<mp[u].size();i++)
    {
        int x=mp[u][i];
        if(vis[x]==0)
        {
            sum+=v[x];
            vis[x]=1;
            if(f==1)return ;
            dfs(x);
            if(f==1)return ;
            vis[x]=0;//不是通往1的路要返回来标记为没走过
            sum-=v[x];//减去之前加的;
        }
    }
}
int main()
{
    int i,j,k=1;
    while(~scanf("%d%d",&n,&m))
    {
        for(i=1;i<=n;i++)mp[i].clear();
        sum=0;
        for(i=0;i<m;i++) scanf("%d",&a[i]);
        for(i=1;i<=n;i++) scanf("%d",&v[i]);
        for(i=0;i<n-1;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            mp[x].push_back(y);
            mp[y].push_back(x);
        }
        for(i=0;i<m;i++)
        {
            f=0;
            memset(vis,0,sizeof(vis));
            sum+=v[a[i]];
            v[a[i]]=0;
            dfs(a[i]);
            for(j=1;j<=n;j++)if(vis[j]==1)v[j]=0;//走过的点礼物数置零
        }
        printf("Case #%d: %d\n",k++,sum);
    }
    return 0;
}
/*
7 7
1 2 3 4 5 6 7
1 2 3 4 5 6 7
3 7
3 5
3 2
2 4
2 1
1 6
*/
View Code

 

 

posted @ 2019-05-15 17:20  -第4题-  阅读(210)  评论(0编辑  收藏  举报