您的位置:首页 > 其它

Light OJ 1230 Placing Lampposts(简单树形DP)

2016-04-04 21:27 423 查看
解析:dp[u][0]在以u为根的子树中,顶点u不安装的最少安装数目;dp[u][1]在以u为根的子树中,顶点u安装的最少安装数目。

则有 dp[u][0] = sigma(dp[v][1]);dp[u][1] = sigma(min(dp[v][0],dp[v][1]))。

再开一个num[][2]数组记录每个状态下的两端点都安装了的边数。

:

[code]#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

struct Nod{
int b,next;
void init(int b,int next){
this->b=b;this->next=next;
}
}buf[2005];
int n,m,len,E[1005];
int dp[1005][2],num[1005][2],vis[1005];

void init(){
len = 0;
memset(E,-1,sizeof(E));
memset(vis,0,sizeof(vis));
}
void add_edge(int a,int b){
buf[len].init(b,E[a]);E[a]=len++;
buf[len].init(a,E[b]);E[b]=len++;
}
void dfs(int u,int pre){
int i,v;
dp[u][0] = 0,dp[u][1] = 1;
num[u][0] = num[u][1] = 0;
vis[u] = 1;
for(i = E[u];i != -1;i = buf[i].next){
v = buf[i].b;
if(v == pre) continue;
dfs(v,u);
dp[u][0] += dp[v][1];
num[u][0] += num[v][1];
dp[u][1] += min(dp[v][0],dp[v][1]);
if(dp[v][0]>dp[v][1]){
num[u][1] += num[v][1]+1;
}else if(dp[v][0]<dp[v][1]){
num[u][1] += num[v][0];
}else num[u][1] += max(num[v][0],num[v][1]+1);
}
}
int main(){
int i,j,cas,a,b;
scanf("%d",&cas);
for(int T=1;T<=cas;T++){
scanf("%d%d",&n,&m);
init();
for(i = 0;i < m;i++){
scanf("%d%d",&a,&b);
add_edge(a,b);
}
int o1,o2;o1 = o2 = 0;
for(i = 0;i < n;i++){
if(vis[i]) continue;
dfs(i,-1);
o1 += min(dp[i][0],dp[i][1]);
if(dp[i][0]>dp[i][1]) o2 += num[i][1];
else if(dp[i][0]<dp[i][1]) o2 += num[i][0];
else o2 += max(num[i][1],num[i][0]);
}
printf("Case %d: %d %d %d\n",T,o1,o2,m-o2);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: