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 */