FZU2169 shadow题解

http://acm.fzu.edu.cn/problem.php?pid=2169




Problem
Description

YL 是shadow国的国王,shadow国有N个城市。为了节省开支,shadow国只有N-1条道路,这N-1条道路使得N个城市连通。某一
年,shadow国发生了叛乱,叛军占领了多个城市,王都岌岌可危。王都为编号为1的城市,除了王都外有K个城市有YL的军队。现在这K支军队要向王都进
军,并且消灭沿途经过的城市中的叛军。现给出N个城市的道路情况以及城市的叛军数量,问总共需要消灭多少叛军?

Input


一行输入两个整数N,K,接下来输入N(1<=N<=100000)个整数Ai(0<=Ai<=10000),表示第i个城市的
叛军数量。接下来输入K个大于等于1且小于等于N的整数,表示有军队的城市的编号。数据保证王都以及有军队的城市没有叛军。接下来输入N-1行,每行两个
整数u、v,表示连接u和v的一条道路。每支军队只能沿着道路走,并且是其所在城市与王都之间的最短路线走。

Output

输出一行一个整数表示消灭的叛军数量。

Sample
Input

4 2 0 3 0 0 3 4 1 2 2 3 2 4

Sample
Output

3

题意:N<=10万个点,N-1条边使所有点连通,点编号为1~N,1号点为国王所在地,给出K个编号表示这K个点有国王的军队,给出Ai表示第i个点有Ai个叛军,国王所在地和有国王军的地方没叛军。现在国王的军队以最短路向国王所在地移动,消灭沿途所有叛军,求消灭的叛军数。

解:用STL的set记国王军所在地,从国王所在地开始宽搜,从当前点u扩展节点时记录扩展节点v来自哪里,from[v]=u。搜到一个国王军就把之前走的这条路上的点的叛军数加到ans里,并且对沿途的点标记geted[x]=true,一开始先标记国王所在地geted[0]=true,这样每次找到一个国王军就把国王军到geted为true的点之间的叛军数加到ans里,并且统计找到的国王军数cnt++。cnt==K时就找够全部国王军了,结束。是不是很碉,只要一次宽搜就得了耶!

  1 #include<iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include<vector>
6 #include<queue>
7 #include<set>
8 #define MAXN 101111
9 #define RE freopen("in.txt","r",stdin);
10
11 using namespace std;
12
13 struct Edge
14 {
15 int u,v;
16 int next;
17 };
18 Edge e[MAXN*2];
19 int first[MAXN];
20 int en;
21
22 void add(int u,int v)
23 {
24 e[en].u=u;
25 e[en].v=v;
26 e[en].next=first[u];
27 first[u]=en;
28 en++;
29 }
30
31 int n,k,cnt;
32 int a[MAXN];
33 set<int> b;
34 bool walked[MAXN];
35 bool geted[MAXN];
36 queue<int> v;
37 int from[MAXN];
38 int farm();
39 void init();
40
41 int main()
42 {
43 //RE
44 while(scanf("%d%d",&n,&k)!=EOF)
45 {
46 farm();
47 }
48 return 0;
49 }
50
51 int farm()
52 {
53 int i,j,x,y;
54 init();
55 for(i=0; i<n; i++)
56 scanf("%d",&a[i]);
57 for(i=0; i<k; i++)
58 {
59 scanf("%d",&x);
60 x--;
61 b.insert(x);
62 }
63 for(i=0; i<n-1; i++)
64 {
65 scanf("%d%d",&x,&y);
66 x--;y--;
67 add(y,x);
68 add(x,y);
69 }
70 long long ans=0;
71 while(!v.empty()) v.pop();
72 v.push(0);
73 walked[0]==true;
74 geted[0]=true;
75 while(!v.empty())
76 {
77 int now=v.front();
78 v.pop();
79 //cout<<now<<‘!‘;
80 if(b.find(now)!=b.end())
81 {
82 //cout<<now<<‘,‘;
83 x=now;
84 while(!geted[x])
85 {
86 geted[x]=true;
87 ans+=a[x];
88 x=from[x];
89 }
90 cnt++;
91 if(cnt==k) break;
92 continue;
93 }
94 for(j=first[now]; j!=-1; j=e[j].next)
95 {
96 //cout<<j<<‘?‘;
97 int next=e[j].v;
98 if(!walked[next])
99 {
100 walked[next]=true;
101 v.push(next);
102 from[next]=now;
103 }
104 }
105 }
106 printf("%lld\n",ans);
107 return 0;
108 }
109
110
111 void init()
112 {
113 memset(e,0,sizeof(e));
114 memset(first,-1,sizeof(first));
115 memset(walked,false,sizeof(walked));
116 memset(geted,false,sizeof(geted));
117 b.clear();
118 cnt=0;
119 en=0;
120 }

话说我交的时候突然想起set没清空,不过还是过了,难道只有一组数据…

不过耗时好像比其他方法久……好像可以手动开栈 深搜,我也不太懂怎么弄的

时间: 2024-07-28 17:48:26

FZU2169 shadow题解的相关文章

FZU2169:shadow(最短路)

Problem Description YL是shadow国的国王,shadow国有N个城市.为了节省开支,shadow国只有N-1条道路,这N-1条道路使得N个城市连通.某一年,shadow国发生了叛乱,叛军占领了多个城市,王都岌岌可危.王都为编号为1的城市,除了王都外有K个城市有YL的军队.现在这K支军队要向王都进军,并且消灭沿途经过的城市中的叛军.现给出N个城市的道路情况以及城市的叛军数量,问总共需要消灭多少叛军?  Input 第一行输入两个整数N,K,接下来输入N(1<=N<=100

cdoj 26 遮挡判断(shadow) 水题

遮挡判断(shadow) Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/26 Description 在一个广场上有一排沿着东西方向排列的石柱子,阳光从东边以一定的倾角射来(平行光).有的柱子可能被在他东边的高大的柱子的影子给完全遮挡住了.现在你要解决的问题是求出有多少柱子是没有被完全遮挡住的. 假设每个石柱子是一根细棒,而且都垂直于地面摆放. Input 输入包含多组数据

【题解】二维凸包

[题解]二维凸包 呵呵呵复习一下这个东西免得做到计算几何连暴力都不会嘤嘤嘤 免得到时候写斜率优化结果凸包不会了嘤嘤嘤 数学走起: \[ \vec{a}=(x_1,y_1),\vec{b}=(x_2,y_2) \shadow_{|\vec{a} \times\vec{b}|}=x_1y_2-x_2y_1 \] 根据右手螺旋定则.\(shadow\)是我乱搞的符号,虽然我搞不懂为什么是这样,但是这个应该和\(\sin(0.5\pi)=1,\sin0=0\)有关,就不纠结了,也比较好记. 遵循\(an

洛谷 P1079 Vigen&#232;re 密码 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1079 题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为 南军所广泛使用. 在密码学中,我们称需要加密的信息为明文,用 M 表示:称加密后的信息为密文,用 C 表示:而密钥是一种

passwd、shadow、group结构及各字段含义

/etc/password结构 sample:root:x:0:0:root:/root:/bin/bash 账号名称 密码 UID GID 用户信息说明 家目录 Shell root x 0 0 root /root /bin/bash /etc/shadow结构: sample:root:$1$/30QpE5e$y9N/D0bh6rAACBEz.hqo00:14126:0:99999:7::: 账号名称 密码 最近更动密码的日期 密码不可被更动的天(0代表随时可以变动) 密码需要重新变更的天

8.8联考题解

今天的T1让我怀疑我是不是在做奥赛题--这考的是什么知识点啊这个,会不会用绝对值函数? Evensgn 的债务 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Evensgn 有一群好朋友,他们经常互相借钱.假如说有三个好朋友A,B,C.A 欠 B 20 元,B 欠 C 20 元,总债务规模为 20+20=40 元.Evensgn 是个追求简约的人,他觉得这样的债务太繁杂了.他认为,上面的债务可以完全等价为 A 欠C20 元,B 既不欠别人,别人也不欠他.这样总债务规模就压缩到了 

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

(leetcode题解)Pascal&#39;s Triangle

Pascal's Triangle  Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 题意实现一个杨辉三角. 这道题只要注意了边界条件应该很好实现出来,C++实现如下 vector<vector<int>> generate(int

2017ZZUACM省赛选拔试题部分题解----谨以纪念我这卡线滚粗的美好经历

写在前面: 其实心里有些小小的不爽又有点小小的舒畅,为啥捏?不爽当然是因为没被选拔上啦,舒畅捏则是因为没被选拔上反而让自己警醒,学长也提点很多很多."沉下去,然后一战成名"学长如是对我说,我很开心.其实这完全算不算是题解,只是我个人的一些小想法而已.而且到现在还有一题不会...让自己长点记性吧. 题目 A :聪明的田鼠 Time Limit: 1 Sec Memory Limit: 128 MB Description 田鼠MIUMIU来到了一片农田,农田可以看成是一个M*N个方格的矩