SRM 477 DIV1 1000

来源:互联网 发布:贵州中小企业数据统计 编辑:程序博客网 时间:2024/04/28 04:36

题意:给定一棵树,最多可给这棵树增加k条捷径,每条捷径长度为L,且只能走一次,问从0出发回到0遍历所有的边需要走的最短距离。


树型dp,状态为dp[i][j][2]。

dp[i][j][0]表示从i出发,用了j次捷径,遍历完下面所有边且最后走的路径到底后没有回来的最小距离。

dp[i][j][1]表示从i出发,用了j次捷径,遍历完下面所有边且回到i的最小距离。

转移看代码:


#include <cstdio>#include <iostream>#include <cstring>#include <sstream>#include <algorithm>#include <cmath>#include <vector>#define clr(x,y) memset(x,y,sizeof(x))#define Min(x,y) if(y<x) x=y#define Max(x,y) if(y>x) x=yusing namespace std ;typedef long long ll ;const double eps = 1e-6 ;const int inf = 1e8;vector<int> ev[205],ew[205];int dp[205][105][2],p[105][2];string s = "";int K,L;class KingdomTour{public:    void dfs(int u,int f){        for(int i=0;i<=K;i++) dp[u][i][0] = dp[u][i][1] = 0;        for(int i=0;i<(int)ev[u].size();i++){            int v = ev[u][i];            int w = ew[u][i];            if(v==f) continue;            dfs(v,u);            for(int i=0;i<=K;i++) p[i][0] = p[i][1] = inf;            for(int i=0;i<=K;i++)                for(int j=0;j<=K;j++)                    if(i+j<=K){                        Min(p[i+j+1][0],dp[u][i][0]+dp[v][j][0]+L+w);                           //之前有儿子节点不回来, v最后通过捷径回到u                        Min(p[i+j][0],dp[u][i][0]+dp[v][j][1]+2*w);                             //之前有儿子节点不回来, v直接走回到u                        Min(p[i+j][0],dp[u][i][1]+dp[v][j][0]+w);                               //之前没有儿子节点不回来,v不回到u                            Min(p[i+j][1],dp[u][i][1]+dp[v][j][1]+2*w);                             //之前没有儿子节点不回来,v直接走回到u                        Min(p[i+j+1][1],dp[u][i][1]+dp[v][j][0]+w+L);                           //之前没有儿子节点不回来,v最后通过捷径回到u                        Min(p[i+j+1][1],dp[u][i][0] + dp[v][j][0]+L+w);                             //之前有儿子节点不回来,直接走到当前儿子叶子节点走回来。                    }            for(int i=0;i<=K;i++){                dp[u][i][0] = p[i][0];                dp[u][i][1] = p[i][1];            }        }    }void get(int &w,int &i){    w = 0;    while(i<(int)s.size() && s[i]<='9' && s[i]>='0'){            w = w*10 +s[i]-'0';            i++;    }        i++;}int minTime(int N, vector <string> roads, int K, int L){    ::K = K;    ::L = L;    s = "";        for(int i=0;i<(int)roads.size();i++) s += roads[i];        for(int i=0;i<N;i++) ev[i].clear(),ew[i].clear();        int l = 0;        while(1){            int u,v,w;            get(u,l);            get(v,l);            get(w,l);            ev[u].push_back(v);ew[u].push_back(w);            ev[v].push_back(u);ew[v].push_back(w);            if(l>=(int)s.size()) break;        }        dfs(0,0);        int ans = inf;        for(int i=0;i<=K;i++) ans = min(ans,dp[0][i][1]);return ans;}};// Powered by FileEdit// Powered by TZTester 1.01 [25-Feb-2003]// Powered by CodeProcessor



原创粉丝点击