题目链接:shadow
先粘代码,明天补充。
#include<stdio.h> #include<vector> #include<string.h> #include<queue> #include<iostream> #include<algorithm> using namespace std; const int maxn=100015; const int inf=0x7fffffff; int father[maxn]; struct Edge { int to; int net; } edge[maxn<<1]; int head[maxn],tot; bool vis[maxn]; //spfa算法中 该点是否已经入队列 int dist[maxn]; // 源点到每个点的最短距离 int n; // 点的个数 int num[maxn]; // 每个地方的叛军数量 int point[maxn]; // YL军队所在城市 bool flag[maxn]; //叛军是否已经被消灭 void addedge(int u,int v) { edge[tot].to=v; edge[tot].net=head[u]; head[u]=tot++; } void spfa(int start) { for(int i=0; i<=n; i++) { vis[i]=false; dist[i]=inf; } vis[start]=true; dist[start]=0; queue<int >que; que.push(start); while(!que.empty()) { int u=que.front(); que.pop(); vis[u]=false; for(int i=head[u]; i!=-1; i=edge[i].net) { int v=edge[i].to; if(dist[v]>dist[u]+1) { dist[v]=dist[u]+1; if(!vis[v]) { father[v]=u; vis[v]=true; que.push(v); } } } } } int main() { int k; while(scanf("%d%d",&n,&k)!=EOF) { for(int i=0; i<=n; i++) { father[i]=-1; flag[i]=false; head[i]=-1; } tot=0; for(int i=1; i<=n; i++) scanf("%d",&num[i]); for(int i=0; i<k; i++) scanf("%d",&point[i]); int u,v; for(int i=1; i<n; i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } int ans=0; spfa(1); for(int i=0; i<k; i++) { int root=point[i]; while(father[root]!=-1) { root=father[root]; if(flag[root]) break; ans+=num[root]; flag[root]=true; } } printf("%d\n",ans); } return 0; }
时间: 2024-10-21 12:17:46