社区讨论

照博客思路自己打就TLE,把博客里的代码拖进去就AC...

P3177[HAOI2015] 树上染色参与者 10已保存回复 32

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
32 条
当前快照
1 份
快照标识符
@mi6uoexk
此快照首次捕获于
2025/11/20 11:06
4 个月前
此快照最后确认于
2025/11/20 16:42
4 个月前
查看原帖
前面一直TLE MLE,我已经气急败坏了,拷博客代码实属无奈之举,敬请见谅。希望管理员大人不要安排我。
CPP
#include <cstdio>
#include <algorithm>
#include <vector>
#define LL long long
#define REP(i,x,y) for (register int i=(x);i<=(y);i++)
#define PER(i,x,y) for (register int i=(x);i>=(y);i--)
#define ERG for (register int i=0;i<to[u].size();i++)
using namespace std;

const LL N=2010,INF=1e15;
LL n,k,u,v,w;
LL fat[N],son[N];
LL f[N][N];
vector <LL> to[N],sp[N]; 

inline void DFS(LL u,LL fa){
    son[u]=1;fat[u]=fa;
    ERG{
        LL v=to[u][i];
        if (v==fa) continue;
        DFS(v,u);
        son[u]+=son[v];
    }
}

inline void WORK(LL u){
    f[u][0]=f[u][1]=0;
    if (son[u]==1) return;
    ERG{
        LL v=to[u][i],val=sp[u][i];
        if (v==fat[i]) continue;
        WORK(v);
        int x=min(son[u],k),y=min(son[v],k);
        PER(tot,x,0) REP(j,0,min(tot,y)){
            LL ans1=(LL)j*(k-(LL)j)*val;
            LL ans2=(son[v]-(LL)j)*(n-k-son[v]+(LL)j)*val;
            LL tmp=f[v][j]+ans1+ans2;
            f[u][tot]=max(f[u][tot],f[u][tot-j]+tmp);
        }
    }
}

int main(){
    scanf("%lld%lld",&n,&k);
    REP(i,1,n-1){
        scanf("%lld%lld%lld",&u,&v,&w);
        to[u].push_back(v);to[v].push_back(u);
        sp[u].push_back(w);sp[v].push_back(w); 
    }
    REP(i,1,n) REP(j,1,n) f[i][j]=-INF;
    DFS(1,0);WORK(1);
    printf("%lld\n",f[1][k]);
    return 0;
}
CPP
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long LL;
const LL inf=1e15,maxn=2010;
LL N,K;
vector<LL> to[maxn],cost[maxn];
LL fa[maxn],f[maxn][maxn],siz[maxn];
inline void dfs(LL x,LL fath){
    fa[x]=fath; siz[x]=1;
    for(int i=0;i<to[x].size();i++){
        LL y=to[x][i];
        if(y!=fath){
            dfs(y,x);
            siz[x]+=siz[y];
        }
    }
}
 
inline void calc(LL x){//计算以x为根的情况 
    f[x][0]=0; f[x][1]=0;
    if(siz[x]==1) return ;//叶子节点
    for(int i=0;i<to[x].size();i++){//枚举子树 
        LL y=to[x][i],val=cost[x][i]; 
        if(y!=fa[x]){
            calc(y);
            for(int tot=min(K,siz[x]);tot>=0;tot--){//枚举以x为根的子树中有几个黑点  
                for(int j=0;j<=min(siz[y],K)&&j<=tot;j++){//这个子树中有多少黑点 
                    LL ans1=(LL)j*(K-(LL)j)*val;
                    LL ans2=(siz[y]-(LL)j)*(N-K-(siz[y]-(LL)j))*val;
                    LL tmp=f[y][j]+ans1+ans2;
                    f[x][tot]=max(f[x][tot],f[x][tot-j]+tmp);   
                }
            }
        }
    }
}
 
int main(){
    scanf("%lld%lld",&N,&K);
    for(int i=1;i<=N-1;i++){
        LL u,v,c;
        scanf("%lld%lld%lld",&u,&v,&c);
        to[u].push_back(v); cost[u].push_back(c);
        to[v].push_back(u); cost[v].push_back(c);
    }
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            f[i][j]=-inf;
        }
    }
    dfs(1,-1);
    calc(1);
    printf("%lld\n",f[1][K]);
    return 0;
}

回复

32 条回复,欢迎继续交流。

正在加载回复...