您的位置:首页 > 其它

uva 10859 树形dp

2016-02-05 22:10 337 查看
题目:点我

又学到了一种得到最优解新的方法,设函数y=kx+b,如果要得到一个x最小时,b也最小的解,不妨设一个k,让

k至少要> (bMax-xMin),然后令dp[]=kx+b;

这样求得最优解ans后,最小x=ans/k,最小b=ans%k;

关于树形dp的这种问题,懒得多说。。。

不过我看题目时,无向无环图,始终没弄明白就是森林,唉,然后就想不出来了,可悲啊!

/**==========================================
* This is a solution for ACM/ICPC problem
*
* @source:uva 10859
* @type: dp
* @author: wust_ysk
* @blog: http://blog.csdn.net/yskyskyer123 * @email: 2530094312@qq.com
*===========================================*/
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn=1000 ;
const int M=2500 ;
int n,m;
vector<int > G[maxn+20];
int dp[maxn+5][2];
void add_edge(int x,int y)
{
G[x].push_back(y);
G[y].push_back(x);
}

void init()
{
for(int i=0;i<n;i++)
G[i].clear();

}

void dfs(int x,int fa)
{
dp[x][0]=0,dp[x][1]=M;
for(int i=0;i<G[x].size();i++)
{
int y=G[x][i];
if(y==fa) continue;
dfs(y,x);
dp[x][0]+=dp[y][1]+1;
dp[x][1]+=min(dp[y][0]+1,dp[y][1]);
}

}
int main()
{
int T,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add_edge(x,y);
}
memset(dp,-1,sizeof dp);
int all=0,one=0;
for(int i=0;i<n;i++) if(dp[i][0]==-1)
{
dfs(i,-1);
int ans=min(dp[i][0],dp[i][1] );
all+= ans/M;
one+=ans%M;
}
printf("%d %d %d\n",all,m-one,one);

}

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