「UVA 10859」题解
Description
Link
给定一棵树,选其中的一些点使每条边都与至少一个所选点相邻。
在满足上述条件的情况下,使得被两个点同时相邻的边最多。
其中 \(1\leq n\leq10^3\)。
Solution
经典的换根 DP。
如果只考虑要求 1,设 \(dp[i][0]\) 表示 i 选不选(0/1)时照亮所有 i 的子节点所需要的最少灯数。
则:
- \(dp[i][0]=\sum_{j=1}^{son[i]}dp[j][1]\)
- \(dp[i][1]=\sum_{j=1}^{son[i]}\min(dp[j][0],dp[j][1])\)
i 选,那么子节点可选可不选,i能全部照亮。
i 不选,那么每条边都只能子节点来照亮,所以所有子节点必选。
设 \(f[i][0]\) 表示在满足条件 1 的情况下,i 选不选,在 i 的子树中被两个点照亮的边的数量最大值。
如果 i 不选,依然所有的子节点都必选。
- \(f[i][0]=\sum_{j=1}^{son[i]}f[j][1]\)
否则,查看 \(dp[j][0]\) 和 \(dp[j][1]\) 的值,判断 \(dp[i][0]\) 由哪一个值得来,那么 \(f[i][0]\) 也由对应的 \(f[j][0/1]\) 得来。
最后统计答案时按满足条件 1 的最优情况判断即可。
具体可见代码。
Code:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=1e3+5;
int t,n,m,head[MAXN<<1],cnt,dp[MAXN][2],pd[MAXN][2];
bool vis[MAXN];
struct ren{
int next,to;
}a[MAXN<<1];
void add(int x,int y)
{
a[++cnt].to=y;
a[cnt].next=head[x];
head[x]=cnt;
}
void dfs(int now,int fa)
{
vis[now]=1;
dp[now][1]=1,dp[now][0]=0;
for(int i=head[now];i;i=a[i].next)
{
int v=a[i].to;
if(v==fa)
{
continue;
}
dfs(v,now);
dp[now][1]+=min(dp[v][1],dp[v][0]);
dp[now][0]+=dp[v][1];
}
}
void DP(int now,int fa){
pd[now][0]=pd[now][1]=0;//pd数组即为上文的f数组
for(int i=head[now];i;i=a[i].next)
{
int v=a[i].to;
if(v==fa)
{
continue;
}
DP(v,now);
pd[now][0]+=pd[v][1];
if(dp[v][0]<dp[v][1])
{
pd[now][1]+=pd[v][0];
continue;
}
if(dp[v][1]<dp[v][0])
{
pd[now][1]+=pd[v][1]+1;
continue;
}
pd[now][1]+=max(pd[v][0],pd[v][1]+1);
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
int ans=0,tot=0;
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x++;
y++;
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
dfs(i,0);
ans+=min(dp[i][0],dp[i][1]);
DP(i,0);
if(dp[i][0]<dp[i][1])
{
tot+=pd[i][0];
continue;
}
if(dp[i][1]<dp[i][0])
{
tot+=pd[i][1];
continue;
}
tot+=max(pd[i][1],pd[i][0]);
}
}
printf("%d %d %d\n",ans,tot,m-tot);
}
return 0;
}
\(\Bbb{End.}\)
\(\Bbb{Thanks}\) \(\Bbb{For}\) \(\Bbb{Reading.}\)
本文来自博客园,作者:{StranGePants},转载请注明原文链接:https://www.cnblogs.com/StranGePants/p/15154605.html