您的位置:首页 > 其它

UVA 10859 Placing Lampposts(树上dp)

2016-09-06 00:05 295 查看
http://acm.hust.edu.cn/vjudge/contest/131137#problem/G

题解:

大白书上的题目,树上dp。

首先,图可能不连通,由几个子图构成。

这道题有一个技巧,就是需要两个答案时,可以使用mod数,mod数的取值比第二个数最大值与最小值的差值还大就可以了。然后小的不管怎么改变都不会影响大的数,但是需要防止超过了int范围。

然后就是树形dp了。

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e3+5;
const int M=2007;

vector<int> G[maxn];
int dp[maxn][2];

int dfs(int now,int sta,int fa) {
if(~dp[now][sta])
return dp[now][sta];

int len=(int)G[now].size();
int &ans=dp[now][sta];
ans=M;
for(int i=0; i<len; ++i) {
int to=G[now][i];
if(to^fa) {
ans+=dfs(to,1,now);
}
}
if(fa>=0 &&(!sta))++ans;
if(sta || fa==-1) {
int S=0;
for(int i=0; i<len; ++i) {
int to=G[now][i];
if(to^fa) {
S+=dfs(to,0,now);
}
}
ans=min(ans,S+(fa!=-1));
}
return ans;
}

int main() {
int n,m,T,u,v;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
for(int i=0; i<n; ++i)G[i].clear();
for(int i=0; i<m; ++i) {
scanf("%d%d",&u,&v);
G[u].push_back(v),G[v].push_back(u);
}
memset(dp,-1,sizeof(dp));
int ans=0;
for(int i=0; i<n; ++i) {
if(dp[i][0]==-1) {
ans+=dfs(i,0,-1);
}
}
printf("%d %d %d\n",ans/M,m-ans%M,ans%M);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: