FZU 2169 shadow
思路:题目大意是求树上两点之间的路径,dfs和bfs均可
dfs:从王都一直深搜,如果搜到军队,则返回true,表明该dfs路径上的敌人均要消灭,最后输出ans,有一点要注意,用G++交会RE,C++交才AC,,
代码:
#pragma comment(linker,"/STACK:102400000:102400000")
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100007
struct Edge{
int v;
int next;
Edge(){}
Edge(int a,int b):v(a),next(b){}
};
Edge edge[N*2];
int head[N],enemy[N];
bool vis[N];
int tot,ans;
void init(){
tot=0;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
}
void addEdge(int u,int v){
edge[tot]=Edge(v,head[u]);
head[u]=tot++;
}
bool dfs(int u,int pre){
bool flag=vis[u];
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(v==pre) continue;
flag=flag||vis[v];
flag=flag||dfs(v,u);
}
if(flag){
ans+=enemy[u];
enemy[u]=0;
}
return flag;
}
int main(){
int n,k;
while(scanf("%d%d",&n,&k)==2){
init();
for(int i=1;i<=n;++i){
scanf("%d",&enemy[i]);
}
int tmp,u,v;
for(int i=1;i<=k;++i){
scanf("%d",&tmp);
vis[tmp]=true;
}
for(int i=1;i<n;++i){
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
ans=0;
dfs(1,-1);
cout<<ans<<endl;
}
return 0;
}
bfs:以王都为根节点先进行一遍树的广搜,记录每个节点的前驱结点,用pre[i]存储,最后遍历军队的所在节点,一直找前驱结点,同时记录消灭敌人数,并用数组vis[i]标记该节点的敌人已被消灭,直到根节点王都
代码:
#pragma comment(linker,"/STACK:102400000:102400000")
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100007
struct Edge{
int v;
int next;
Edge(){}
Edge(int a,int b):v(a),next(b){}
};
Edge edge[N*2];
int head[N],enemy[N],army[N],pre[N];
bool vis[N];
int tot,ans;
void init(){
tot=0;
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
}
void addEdge(int u,int v){
edge[tot]=Edge(v,head[u]);
head[u]=tot++;
}
void bfs(int s){
queue<int> q;
pre[s]=s;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(v==pre[u]) continue;
pre[v]=u;
q.push(v);
}
}
}
int main(){
int n,k;
while(scanf("%d%d",&n,&k)==2){
init();
for(int i=1;i<=n;++i){
scanf("%d",&enemy[i]);
}
int u,v;
for(int i=1;i<=k;++i){
scanf("%d",&army[i]);
}
for(int i=1;i<n;++i){
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
bfs(1);
ans=0;
for(int i=1;i<=k;++i){
u=army[i];
while(pre[u]!=u&&!vis[u]){
ans+=enemy[u];
vis[u]=true;
enemy[u]=0;
u=pre[u];
}
}
cout<<ans<<endl;
}
return 0;
}