YL是shadow國的國王,shadow國有N個城市。為了節省開支,shadow國只有N-1條道路,這N-1條道路使得N個城市連通。某一年,shadow國發生了叛亂,叛軍占領了多個城市,王都岌岌可危。王都為編號為1的城市,除了王都外有K個城市有YL的軍隊。現在這K支軍隊要向王都進軍,並且消滅沿途經過的城市中的叛軍。現給出N個城市的道路情況以及城市的叛軍數量,問總共需要消滅多少叛軍?
第一行輸入兩個整數N,K,接下來輸入N(1<=N<=100000)個整數Ai(0<=Ai<=10000),表示第i個城市的叛軍數量。接下來輸入K個大於等於1且小於等於N的整數,表示有軍隊的城市的編號。數據保證王都以及有軍隊的城市沒有叛軍。接下來輸入N-1行,每行兩個整數u、v,表示連接u和v的一條道路。每支軍隊只能沿著道路走,並且是其所在城市與王都之間的最短路線走。<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KCjxoMj48aW1nIHNyYz0="https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017012114360108.gif" alt="\"> Output
輸出一行一個整數表示消滅的叛軍數量。
#include#include #include #include using namespace std; const int inf = 1<<30; const int L = 100005; struct Edges { int x,y,w,next; } e[L<<2]; int head[L]; int dis[L]; int vis[L]; int cnt[L],hash[L],ss[L]; int s[L]; void AddEdge(int x,int y,int w,int k) { e[k].x = x,e[k].y = y,e[k].w = w,e[k].next = head[x],head[x] = k; } int relax(int u,int v,int c) { if(dis[v]>dis[u]+c) { dis[v] = dis[u]+c; return 1; } return 0; } int SPFA(int src) { int i; memset(vis,0,sizeof(vis)); dis[src] = 0; queue Q; Q.push(src); vis[src] = 1; while(!Q.empty()) { int u,v; u = Q.front(); Q.pop(); vis[u] = 0; for(i = head[u]; i!=-1; i=e[i].next) { v = e[i].y; if(relax(u,v,e[i].w)==1 && !vis[v]) { Q.push(v); vis[v] = 1; } } } } int main() { int t,n,k; int i,j; while(~scanf("%d%d",&n,&k)) { memset(e,-1,sizeof(e)); for(i = 1; i<=n; i++) { dis[i] = inf; head[i] = -1; hash[i] = 0; } int cnt = 0; for(i = 1; i<=n; i++) { scanf("%d",&s[i]); if(s[i]) { hash[i] = 1; cnt++; } } for(i = 1; i<=k; i++) { scanf("%d",&ss[i]); } for(i = 0; i<2*(n-1); i+=2) { int x,y,w; scanf("%d%d",&x,&y); AddEdge(x,y,1,i); AddEdge(y,x,1,i+1); } int ans = 0; for(i = 1; i<=k; i++) { SPFA(ss[i]); for(j = 1; j<=n; j++) { if(!hash[j]) continue; if(dis[s[j]]!=inf) { hash[j] = 0; cnt--; ans+=s[j]; } } if(!cnt) break; } printf("%d\n",ans); } return 0; }