XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem K. Piecemaking

题目:Problem K. Piecemaking
Input file: standard input
Output file: standard output
Time limit: 1 second
Memory limit: 512 mebibytes
The civil war in Berland continues for five years already. The United Nation decided to end the bloodshed.
Berland consists of n cities, connected by n - 1 bidirectional roads, forming a tree. The Purple Army
occupies several cities which are listed in the set A, and the Cian Army occupies cities listed in the set
B. The UN Assembly took an unexpected decision to end the war: they decided to destroy some roads
in Berland, so that no city from the set A is connected (directly or undirectly) with a city from the set
B. This way the enemies wouldn’t be able to reach each other, and the fighting would stop. Destroying
a road of length x kilometers requires x dollars.
Find the minimum sum of money neccessary for peacemaking in Berland.
Input
The first line of the input contains a positive integer n (2 ≤ n ≤ 200 000) — the number of cities in
Berland.
Next n - 1 lines contain information about roads in the form ui, vi, wi (1 ≤ ui; vi ≤ n, 1 ≤ wi ≤ 109) —
indices of cities connected by the i-th road, and the length of this road in kilometers.
The next line contains a positive integer m (1 ≤ m ≤ n) — the number of cities occupied by the Purple
Army, and m distinct integers a1; a2; : : : ; am (1 ≤ ai ≤ n) — indices of these cities.
The next line contains a positive integer k (1 ≤ k ≤ n) and k distinct integers b1; b2; : : : ; bk (1 ≤ bi ≤ n) —
the cities, occupied by the Cian army, in the similar format.
It is guaranteed that no city is occupied by both armies.
Output
Print the minimum possible number of dollars required to make it impossible to reach any city in set B
from any city in set A.
Example

standard input standard output
6
1 2 5
2 4 4
2 5 1
1 3 2
3 6 7
1 4
2 5 6
3

思路:

  比较简单的树dp:dp[i][s]:表示这个点属于空集合,还是A集合,还是B集合?

  转移过程略麻烦。

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define MP make_pair
 6 #define PB push_back
 7 typedef long long LL;
 8 typedef pair<int,int> PII;
 9 const double eps=1e-8;
10 const double pi=acos(-1.0);
11 const int K=1e6+7;
12 const int mod=1e9+7;
13
14 vector<PII>mp[K];
15 int n,m,col[K];
16 LL dp[K][3];
17
18 void dfs(int u,int f)
19 {
20     for(auto v:mp[u])if(v.first!=f) dfs(v.first,u);
21     for(auto v:mp[u])if(v.first!=f)
22     {
23         if(col[u]==0)
24         {
25             if(col[v.first]==0)
26             {
27                 dp[u][0]+=min(dp[v.first][0],min(dp[v.first][1],dp[v.first][2])+v.second);
28                 dp[u][1]+=min(min(dp[v.first][0],dp[v.first][1]),dp[v.first][2]+v.second);
29                 dp[u][2]+=min(min(dp[v.first][0],dp[v.first][2]),dp[v.first][1]+v.second);
30             }
31             else if(col[v.first]==1)
32             {
33                 dp[u][0]+=dp[v.first][1]+v.second;
34                 dp[u][1]+=dp[v.first][1];
35                 dp[u][2]+=dp[v.first][1]+v.second;
36             }
37             else
38             {
39                 dp[u][0]+=dp[v.first][2]+v.second;
40                 dp[u][1]+=dp[v.first][2]+v.second;
41                 dp[u][2]+=dp[v.first][2];
42             }
43         }
44         else if(col[u]==1)
45         {
46             if(col[v.first]==0)
47                 dp[u][1]+=min(min(dp[v.first][0],dp[v.first][1]),dp[v.first][2]+v.second);
48             else if(col[v.first]==1)
49                 dp[u][1]+=dp[v.first][1];
50             else
51                 dp[u][1]+=dp[v.first][2]+v.second;
52         }
53         else
54         {
55             if(col[v.first]==0)
56                 dp[u][2]+=min(min(dp[v.first][0],dp[v.first][2]),dp[v.first][1]+v.second);
57             else if(col[v.first]==1)
58                 dp[u][2]+=dp[v.first][1]+v.second;
59             else
60                 dp[u][2]+=dp[v.first][2];
61         }
62     }
63     if(col[u]==1) dp[u][0]=dp[u][2]=2e14;
64     else if(col[u]==2) dp[u][0]=dp[u][1]=2e14;
65     //printf("%d==%lld %lld %lld\n",u,dp[u][0],dp[u][1],dp[u][2]);
66 }
67 int main(void)
68 {
69     scanf("%d",&n);
70     for(int i=1,x,y,z;i<n;i++)
71         scanf("%d%d%d",&x,&y,&z),mp[x].PB(MP(y,z)),mp[y].PB(MP(x,z));
72     scanf("%d",&m);
73     for(int i=1,x;i<=m;i++) scanf("%d",&x),col[x]=1;
74     scanf("%d",&m);
75     for(int i=1,x;i<=m;i++) scanf("%d",&x),col[x]=2;
76     dfs(1,0);
77     printf("%lld\n",min(min(dp[1][0],dp[1][1]),dp[1][2]));
78     return 0;
79 }
时间: 2024-10-14 00:31:51

XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem K. Piecemaking的相关文章

XVII Open Cup named after E.V. Pankratiev Grand Prix of Moscow Workshops, Sunday, April 23, 2017 Problem D. Great Again

题目: Problem D. Great AgainInput file: standard inputOutput file: standard outputTime limit: 2 secondsMemory limit: 512 megabytesThe election in Berland is coming. The party United Berland is going to use its influence to win themagain. The crucial co

XVII Open Cup named after E.V. Pankratiev. Grand Prix of America (NAIPC-2017)

A. Pieces of Parentheses 将括号串排序,先处理会使左括号数增加的串,这里面先处理减少的值少的串:再处理会使左括号数减少的串,这里面先处理差值较大的串.确定顺序之后就可以DP了. 时间复杂度$O(n^3)$. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=310,inf=1000000; int n,i,j,m,all,

XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Khamovniki

A. Ability Draft 记忆化搜索. #include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<ctype.h> #include<math.h> #include<set> #include<map> #include<vector> #include<queue> #i

XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Khamovniki Problem J Stairways解题报告(分块+维护凸壳)

首先ORZ一发Claris聚聚的题解:http://www.cnblogs.com/clrs97/p/8689215.html,不然我可能没机会补过这道神题了. 这里写一个更详细的题解吧(我还是太菜了啊). 题目描述 有\(n(n \le10^5)\)个人依次进入一个入口,要到一个出口.入口到出口有两条同样长的路.每个人都有一个速度,用通行时间\(a_i(1\le a_i \le 10^6)\)表示,他可以选择任一条路走.但是,若走这条路的前面的人比他慢的话,他只能降到和前面所有人最慢的那个人同

XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.

A. City Wall 一圈一圈绕. B. Domino Colorings C. Сounterquestion 枚举 permutation 后 \(O(len)\) 地 check. D. Galaxy Center 同一层至多经过一个点. 可能 vis 的点不会太多,枚举在哪个点相遇. E. IBM 1403 预处理序列自动机,即可求 \(O(|s|)\) 出当前时间 t 下,打印字符串 s 的时间. F. Line Tracing G. The Queen and the Knigh

【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring

题意:给你一张简单无向图(但可能不连通),再给你一个K,让你求解任意一个问题:K染色或者输出一条K长路径. 直接贪心染色,对一个点染上其相邻的点的颜色集合之中,未出现过的最小的颜色. 如果染成就染成了.如果到某个点,发现染不成,则倒着按照颜色从大到小回去,则一定恰好可以找出一条K长度的路径. #include<cstdio> #include<cstring> using namespace std; int first[1005],next[20005],v[20005],e,c

XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem A. Arithmetic Derivative

题目:Problem A. Arithmetic DerivativeInput file: standard inputOutput file: standard inputTime limit: 1 secondMemory limit: 256 mebibytesLets define an arithmetic derivative:? if p = 1 then p0 = 0;? if p is prime then p0 = 1;? if p is not prime then n0

XVII Open Cup named after E.V. Pankratiev. Eastern GP, Division 1

A. Count The Ones $ans=b-c+1$. #include <stdio.h> using namespace std ; int a , b , c ; void solve () { printf ( "%d\n" , 1 + b - c ) ; } int main () { while ( ~scanf ( "%d%d%d" , &a , &b , &c ) ) solve () ; return 0

XVII Open Cup named after E.V. Pankratiev. GP of SPb

A. Array Factory 将下标按前缀和排序,然后双指针,维护最大的右边界即可. #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=200010; int n,i,j,anslen,ansl,ansr,mr,q[N]; ll a[N],lim; inline bool cmp(int x,int y){return a[x]<a[y];