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