zoukankan      html  css  js  c++  java
  • boj1267 Infinite’s Cave 树形dp + 背包

    题目链接:http://acm.bupt.edu.cn/onlinejudge/newoj/showProblem/show_problem.php?problem_id=1267

       
       
    /**算法分析:
    
    */
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<string>
    #include<map>
    #include<set>
    #include<cmath>
    #include<sstream>
    #include<queue>
    #include<utility>
    
    #define MAXN 505
    #define PI acos(-1.0)
    #define INF 0x3f3f3f3f
    #define REP(i,n) for(int i=0; i<n; i++)
    #define FOR(i,s,t) for(int i=s; i<=t; i++)
    #define show(x) { cerr<<">>>"<<#x<<" = "<<x<<endl; }
    #define showtwo(x,y) { cerr<<">>>"<<#x<<"="<<x<<"  "<<#y<<" = "<<y<<endl; }
    using namespace std;
    
    int n,q;
    int dp1[MAXN][MAXN]; //dp1[i][j]代表以i为根访问j个点并回到第i个点的最小路程代价
    int dp2[MAXN][MAXN]; //dp2[i][j]代表以i为根访问j个点不回到第i个点的最小路程代价
    int num[MAXN];
    vector<pair<int,int> > G[MAXN];
    
    struct Store
    {
        int x,id;
        bool operator < (const Store& rhs) const { return x < rhs.x; }
    }a[MAXN*2];
    int ans[MAXN*2];
    
    void dfs_count(int u)
    {
        num[u] = 1;
        int sz = G[u].size();
        REP(i,sz)
        {
            int v = G[u][i].first;
            dfs_count(v);
            num[u] += num[v];
        }
    }
    
    void dfs(int u,int cnt) //连根一起共访问cnt个点
    {
        if(dp2[u][cnt] != INF) return;
    
        int sz = G[u].size();
        REP(i,sz)
        {
            int v = G[u][i].first;
            int d = G[u][i].second;
    
            dfs(v,num[v]);
    
            for(int k=cnt; k>=2; k--)                 //枚举以u为根的树访问点的个数
                for(int j=1; j<=min(num[v],k-1); j++) //v这个子树要走j个点
            {
                dp1[u][k] = min(dp1[u][k],2*d+dp1[v][j]+dp1[u][k-j]);
                dp2[u][k] = min(dp2[u][k],2*d+dp1[v][j]+dp2[u][k-j]);
                dp2[u][k] = min(dp2[u][k],d+dp2[v][j]+dp1[u][k-j]);
            }
        }
    }
    
    int main()
    {
        //freopen("E:\acm\input.txt","r",stdin);
        int test_count = 1;
        while(cin>>n && n)
        {
            printf("Case %d:
    ",test_count++);
            bool not_root[MAXN];
            memset(not_root,0,sizeof(not_root));
            memset(dp1,0x3f,sizeof(dp1));
            memset(dp2,0x3f,sizeof(dp2));
            REP(i,n) G[i].clear();
            REP(i,n-1)
            {
                int v,u,d;
                scanf("%d%d%d",&v,&u,&d);
                not_root[v] = true;
                G[u].push_back(make_pair(v,d));
            }
            int root;
            REP(i,n) if(!not_root[i]) root = i;
            REP(i,n) dp1[i][1] = dp2[i][1] = dp1[i][0] = dp2[i][0] = 0;
    
            dfs_count(root);
            dfs(root,n);
            //FOR(i,1,n) showtwo(dp2[root][i],num[i-1]);
    
            cin>>q;
            REP(i,q)
            {
                scanf("%d",&a[i].x);
                a[i].id = i;
            }
            sort(a,a+q);
            int ptr = 1;
            REP(i,q)
            {
                while(ptr<=n && dp2[root][ptr] <= a[i].x) ptr++;
                ans[a[i].id] = ptr-1;
            }
            REP(i,q) cout<<ans[i]<<endl;
        }
    }
    View Code
  • 相关阅读:
    python文件打开方式详解——a、a+、r+、w+、rb、rt区别
    io.UnsupportedOperation: can't do nonzero cur-relative seeks”错误
    端口三种模式:access,hybrid,trunk
    水仙花数
    maktrans和translate详解
    实战NFS服务搭建与配置
    except 配合 shell实现公钥分发脚本
    linux系统免秘钥分发文件
    rsync + inotify 实现远程实时同步数据
    通过rsync实现全网数据备份检查脚本
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3592534.html
Copyright © 2011-2022 走看看