uva 10859 树形dp

来源:互联网 发布:善良的男人大结局知乎 编辑:程序博客网 时间:2024/05/22 12:43



题目:点我


又学到了一种得到最优解新的方法,设函数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;}


0 0
原创粉丝点击