SDOI 2006 - 保安站岗
2014-05-20 15:16
337 查看
最小监视覆盖,即选中费用最小的i个点来选中一些边,这些边把所有的点覆盖。
#include <cstdio> using namespace std; #define MAXV 1505 #define MAXE (MAXV - 1) int Vefw[MAXE], Veh[MAXV], Vet[MAXE], Vc[MAXV], Veptr; int dp[MAXV][3],dp2[MAXV]; #define min(a,b) ((a)<(b)?(a):(b)) #define addedge(s,t) do{\ Vefw[Veptr] = Veh[s], Vet[Veptr] = t; \ Veh[s] = ++Veptr;}while(0) void solve(int s) { dp[s][2] = 0, dp[s][1] = Vc[s]; for(int e = Veh[s]; e; e = Vefw[e]) { int t = Vet[--e]; solve(t); dp[s][1] += min(min(dp[t][0], dp[t][1]), dp[t][2]); dp[s][2] += min(dp[t][0], dp[t][1]); } int k; dp2[k=s] = 0x3f3f3f3f; for(int e1 = Veh[s]; e1; e1 = Vefw[e1]) { int t1 = Vet[--e1]; dp2[t1] = dp[t1][1]; for(int e2 = Veh[s]; e2; e2 = Vefw[e2]) { int t2 = Vet[--e2]; if (t2 != t1) dp2[t1] += min(dp[t2][0], dp[t2][1]); } if (dp2[k] > dp2[t1]) k = t1; } dp[s][0] = dp2[k]; } int N; int main(void) { // freopen("sdoi2006_guard.txt", "r", stdin); scanf("%d", &N); int root = 0; for(int i=0; i<N; ++i) { int s, k, c; scanf("%d%d%d", &s, &k, &c); Vc[--s] = k; while(c) { int t; scanf("%d", &t); --t; if (t == root) root = s; addedge(s, t); --c; } } solve(root); printf("%d\n", min(dp[root][0], dp[root][1])); return 0; }
1046 | Accepted | 988 | 0 | C++ | 1421 B | 2014-05-20 14:36:41 |
相关文章推荐
- 【洛谷2458】【SDOI2006】保安站岗(树形DP)
- [luogu 2458][SDOI2006]保安站岗
- Luogu P2458 [SDOI2006]保安站岗【树形Dp】
- [SDOI2006]保安站岗
- [SDOI2006]保安站岗
- [SDOI2006]保安站岗 树dp
- 【Luogu2458】保安站岗(动态规划)
- [SDOI2006]线性方程组 高斯消元
- [SDOI2006]二进制方程 并查集
- [SDOI2006] 仓库管理员的烦恼
- [SDOI2006]仓库管理员的烦恼
- 【SDOI2010】【BZOJ1922】大陆争霸
- bzoj 2281: [Sdoi2011]黑白棋 博弈论+动态规划+排列组合
- 【BZOJ 1050】 [HAOI2006]旅行comf
- 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐
- BZOJ大视野 2190: [SDOI2008]仪仗队
- BZOJ 1510: [POI2006]Kra-The Disks
- BZOJ2006 [NOI2010]超级钢琴(划分树+堆)
- 能量项链 NOIP2006 Codevs1154
- BZOJ系列1193《[HNOI2006]马步距离》题解