Warsaw University Contest Petrozavodsk, Thursday, January 31, 2008 A题,Gym100096A

市长为了提高自己的支持率,决定组织一场跑步比赛。由于城市中没有体育场,比赛将在街道上进行。你需要帮助市长规划赛道,使得同时举行的赛事数量尽可能多,但不能让两条赛道共用同一条街或同一个交叉口。

Problem A.

Athletic competition Input file: athletic.in Output file: athletic.out Elections are coming and the mayor of Bytetown decided to organize an athletic competition to increase his odds. Unfortunately there is no athletic stadium in Bytetown, so all parts of the competition will have to be held in the town’s streets. Mayor decided to limit the competition only to running events and asked you for help with planning their tracks. There are n street junctions and n − 1 streets in Bytetown. From each junction there is a path leading to every other junction. Every running track must start at some junction, lead along some streets and finish at some other junction. Mayor would like to organize as many events simultaneously as possible, so the number of tracks should be maximized. Due to safety reasons no two tracks may have a common junction or street. Additionally, not every junction can be used as a starting or ending point of an event.

Input

The first line of the input file contains a single integer n (1 ≤ n ≤ 200 000), denoting the number of junctions in Bytetown. The junctions are numbered from 1 to n. The following n − 1 lines contain descriptions of the streets; each of them consists of two integers a and b (1 ≤ a, b ≤ n, a 6= b), separated by a single space — numbers of junctions that are connected by the street. Line number n+1 contains one integer m (0 ≤ m ≤ n), denoting the number of junctions that can serve as a starting or ending point of an event. The last line of the input file contains m distinct space–separated numbers — the numbers of those junctions, each in the range [1, n].

Output

The first and only line of the input file should contain one integer, denoting the maximal possible number of running events that can be held in Bytetown simultaneously. Example athletic.in athletic.out 5 1 2 3 2 4 1 1 5 4 1 2 5 4 1 

 

题目分析:

树上贪心,由于树上的路径唯一的性质,很容易想到贪心

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 #define fi first
 4 #define se second 
 5 #define LL long long
 6 #define maxn 200100
 7 using namespace std;
 8 vector<int> G[maxn];
 9 int cnt=0,n,m,size[maxn],in[maxn],col[maxn],pre[maxn];
10 bool vis[maxn];
11 void dfs(int rt,int fa){
12     if(col[rt]) size[rt]++;
13     vis[rt]=true;
14     int now;
15     for(int i=0;i<G[rt].size();i++){
16         now=G[rt][i];
17         if(vis[now]) continue;
18         dfs(now,rt);
19         size[rt]+=size[now];    
20     }
21     return;
22 }
23 void solve(int rt,int fa){
24     vis[rt]=true;
25     int now;
26     for(int i=0;i<G[rt].size();i++){
27         now=G[rt][i];
28         if(vis[now]) continue;
29         solve(now,rt);
30         pre[rt]+=pre[now];
31     }
32     size[rt]-=pre[rt];
33     if(size[rt]>=2){
34         pre[rt]+=size[rt];
35         size[rt]=0;
36         ++cnt;
37     }
38 }
39 int main(){
40     freopen("athletic.in","r",stdin);
41     freopen("athletic.out","w",stdout);
42     int u,v;
43     cin>>n;
44     for(int i=1;i<n;i++){
45         scanf("%d%d",&u,&v);
46         G[u].pb(v);
47         G[v].pb(u);
48         in[v]++;
49         in[u]++;
50     }
51     int root;
52     for(int i=1;i<=n;i++){
53         if(in[i]==1){
54             root=i;
55             break;
56         }
57     }
58     cin>>m;
59     for(int i=1;i<=m;i++){
60         scanf("%d",&u);
61         col[u]=1;
62     }
63     cnt=0;
64     dfs(root,-1);
65     memset(vis,false,sizeof(vis));
66     solve(root,-1);
67     cout<<cnt;
68     return 0;
69 }

 

转载于:https://www.cnblogs.com/poler/p/7342576.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值