UVA 1218 完美的服务
2018-01-26 23:03
405 查看
https://vjudge.net/problem/UVA-1218
这题注意边界情况。在叶子节点d【u】【2】要注意区别取值,我这里采用的maxn标记。
而且d【u】【1】的取值,在u的孩子中如果有叶子节点那么这个策略是行不通的,也要标记。
接下来就是深度搜索了。我跟网上其他人的做法不太一样。这是一个比较易于理解的做法,写出来发现可以过就没再优化。其实计算d【u】【2】可以再快一点,具体看下面分析。
(u,0):u是服务器,则每个子结点可以是服务器也可以不是。
d(u,1):u不是服务器,但u的父亲是服务器,这意味着u的所有子结点都不是服务器。d(u,2):u和u的父亲都不是服务器。这意味着u恰好有一个儿子是服务器。
状态转移比前面复杂一些,但也不困难。首先可以写出:
d(u,0) = sum{min(d(v,0), d(v,1))} + 1
d(u,1) = sum(d(v,2))
而d(u,2)稍微复杂一点,需要枚举当服务器的子结点编号v,然后把其他所有子结
点v’的d(v’,2)加起来,再和d(v,0)相加。不过如果这样做,每次枚举v都需要O(k)时间(其中k是u的子结点数目),而v本身要枚举k次,因此计算d(u,2)需要花O(k 2 )时间。
刚才的做法有很多重复计算,其实可以利用已经算出的d(u,1)写出一个新的状态转移方程:
d(u,2) = min(d(u,1) – d(v,2) + d(v,0))
这题注意边界情况。在叶子节点d【u】【2】要注意区别取值,我这里采用的maxn标记。
而且d【u】【1】的取值,在u的孩子中如果有叶子节点那么这个策略是行不通的,也要标记。
接下来就是深度搜索了。我跟网上其他人的做法不太一样。这是一个比较易于理解的做法,写出来发现可以过就没再优化。其实计算d【u】【2】可以再快一点,具体看下面分析。
(u,0):u是服务器,则每个子结点可以是服务器也可以不是。
d(u,1):u不是服务器,但u的父亲是服务器,这意味着u的所有子结点都不是服务器。d(u,2):u和u的父亲都不是服务器。这意味着u恰好有一个儿子是服务器。
状态转移比前面复杂一些,但也不困难。首先可以写出:
d(u,0) = sum{min(d(v,0), d(v,1))} + 1
d(u,1) = sum(d(v,2))
而d(u,2)稍微复杂一点,需要枚举当服务器的子结点编号v,然后把其他所有子结
点v’的d(v’,2)加起来,再和d(v,0)相加。不过如果这样做,每次枚举v都需要O(k)时间(其中k是u的子结点数目),而v本身要枚举k次,因此计算d(u,2)需要花O(k 2 )时间。
刚才的做法有很多重复计算,其实可以利用已经算出的d(u,1)写出一个新的状态转移方程:
d(u,2) = min(d(u,1) – d(v,2) + d(v,0))
#include<iostream> using namespace std; #include<vector> #include<algorithm> #include<string.h> #define maxn 10000+10 #define INF 100000000 vector<int> child[maxn]; int n; int d[maxn][5]; int vis[maxn]; void initial() { for(int i=0;i<=n;i++) child[i].clear(); memset(d,0,sizeof(d)); } void dfs(int u) { int size=child[u].size(); if(!size)//leaf node { d[u][0]=1; d[u][1]=0; d[u][2]=maxn;// return; } for(int i=0;i<size;i++) { int v=child[u][i]; dfs(v); 4000 d[u][0]+=min(d[v][0],d[v][1]); } d[u][0]++; for(int i=0;i<size;i++) { int v=child[u][i]; if(!child[v].size())//leaf node { d[u][1]=maxn;break; } d[u][1]+=d[v][2]; } int minn=INF; for(int i=0;i<size;i++) { int v=child[u][i]; int sum=d[v][0]; for(int j=0;j<size;j++) { int v1=child[u][j]; if(j==i)continue; sum+=(d[v1][2]>=maxn?0:d[v1][2]); } minn=min(minn,sum); } d[u][2]=minn; return; } int main() { cin>>n; while(1) { initial(); int n1,n2,root; cin>>n1>>n2; vis[n1]=vis[n2]=1; root=n1; child[n1].push_back(n2); for(int i=1;i<=n-2;i++) { cin>>n1>>n2; if(vis[n1]) {child[n1].push_back(n2);vis[n2]=1;} else {child[n2].push_back(n1);vis[n1]=1;} } dfs(root); cin>>n; int a=min(d[root][0],d[root][2]); cout<<a<<endl; if(n==-1) break; cin>>n; } }
相关文章推荐
- 树形DP(完美的服务,uva 1218)
- Uva 1218 完美的服务
- 例题 9-14 完美的服务 UVa 1218
- UVA 1218 完美服务 树形dp
- 树上dp 完美的服务(py)(Perfect Service)(UVa 1218)题解
- [UVa1218]完美服务
- 例题9-14 UVA 1218 Perfect Service 完美的服务(树形dp)
- uva 1218 完美的服务 dp
- UVa 1218 完美的服务
- uva 1218 完美服务器 树形dp 染色问题
- 1218 - Perfect Service(完美服务)
- UVA1218,POJ3398 完美服务器(树形DP)
- wcf完美搭建android平台服务之三
- UVa 1218:Perfect Service(DP)
- 数人云|使微服务、容器趋向完美——Serverless架构你应当知道的二三事
- UVaLive 4043 Ants(二分图最佳完美匹配、KM)
- 《pigcms v6.2最新完美至尊版无任何限制,小猪微信源码多用户微信营销服务平台系统》
- Perfect Service UVA - 1218
- UVA1218 - Perfect Service
- UVa1218 - Perfect Service(树形dp)