社区讨论
照博客思路自己打就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 条回复,欢迎继续交流。
正在加载回复...