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;
}
又学到了一种得到最优解新的方法,设函数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;
}
相关文章推荐
- HDU2824 The Euler function(欧拉函数)
- LeetCode322. Coin Change
- 接口1
- jQuery2(JQuery实现onload)
- 理解javascript中所有的函数参数是按值传递
- junit4X系列--Statement
- c++n连环
- USACO window area 漂浮法
- python 编码格式
- junit4X系列--Runner解析
- struts2学习笔记--struts.xml配置文件详解
- 为什么直接把javascript的代码写进html就行但是调用js文件就不行
- 日志管理
- {A} + {B}
- linux系统如何启用ftp服务
- [LeetCode]Codes of Easy Problem
- HDOJ1238 Substrings
- REDIS源码中一些值得学习的技术细节02
- 猿代码邀请码
- USACO bigborn 最大矩形