【CF1244D】Paint the Tree(树形DP,树)
题意:
n<=1e5,1<=a[i][j]<=1e9
思路:
不是很懂INF为什么要开到1e15,我觉得只要1e14就好
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 200010
#define M 200010
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 struct node
{
int x,y;
}pre[N][][]; ll dp[N][][];
ll a[N][];
int head[N],vet[N],nxt[N],d[N],c[N],son[N],f[N],tot,n; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b)
{
nxt[++tot]=head[a];
vet[tot]=b;
head[a]=tot;
} void dfs(int u,int fa)
{
//printf("dfs u=%d fa=%d\n",u,fa);
int e=head[u],s=;
rep(i,,)
rep(j,,) dp[u][i][j]=1e15;
while(e)
{
int v=vet[e];
if(v!=fa)
{
s++;
son[u]=v;
f[v]=u;
dfs(v,u);
}
e=nxt[e];
}
if(u==&&d[]==)
{
//printf("case 2\n");
return;
} if(s==)
{
rep(i,,)
rep(j,,)
if(i!=j) dp[u][i][j]=a[u][i];
}
else
{
int v=son[u];
//printf("u=%d v=%d\n",u,v);
rep(i,,)
rep(j,,)
rep(k,,)
if(i!=j&&j!=k&&i!=k)
{
if(dp[u][i][j]>dp[v][j][k]+a[u][i])
{
dp[u][i][j]=dp[v][j][k]+a[u][i];
pre[u][i][j].x=j;
pre[u][i][j].y=k;
}
} } } void print()
{
/*rep(i,1,n)
rep(j,0,2)
rep(k,0,2)
if(j!=k) printf("i=%d j=%d k=%d dp[i][j][k]=%I64d\n",i,j,k,dp[i][j][k]);*/
if(d[]==)
{
ll ans=1e15;
int x=,y=;
rep(i,,)
rep(j,,)
if(i!=j&&dp[][i][j]<ans)
{
ans=dp[][i][j];
x=i; y=j;
}
int u=;
while(u)
{
c[u]=x;
int x1=pre[u][x][y].x;
int y1=pre[u][x][y].y;
u=son[u];
x=x1,y=y1;
}
printf("%I64d\n",ans);
rep(i,,n) printf("%d ",c[i]+);
}
else
{
int k1=,k2=;
rep(i,,n)
if(f[i]==){k1=i; break;}
per(i,n,)
if(f[i]==){k2=i; break;}
int x1,y1,x2,y2,z;
ll ans=1e15;
rep(i,,)
rep(j,,)
rep(k,,)
rep(p,,)
rep(q,,)
if(i!=j&&i!=k&&j!=k&&j!=p&&p!=i&&i!=q&&k!=q&&dp[k1][j][p]+dp[k2][k][q]+a[][i]<ans)
{
ans=dp[k1][j][p]+dp[k2][k][q]+a[][i];
z=i;
x1=j; y1=p;
x2=k; y2=q;
}
c[]=z;
int u=k1,x=x1,y=y1;
while(u)
{
c[u]=x;
int x1=pre[u][x][y].x;
int y1=pre[u][x][y].y;
u=son[u];
x=x1,y=y1;
}
u=k2,x=x2,y=y2;
while(u)
{
c[u]=x;
int x1=pre[u][x][y].x;
int y1=pre[u][x][y].y;
u=son[u];
x=x1,y=y1;
}
printf("%I64d\n",ans);
rep(i,,n) printf("%d ",c[i]+);
} } int main()
{
//freopen("1.in","r",stdin);
n=read();
rep(j,,)
rep(i,,n) scanf("%I64d",&a[i][j]);
rep(i,,n) head[i]=d[i]=;
tot=;
rep(i,,n-)
{
int x=read(),y=read();
add(x,y);
add(y,x);
d[x]++; d[y]++;
}
int flag=;
rep(i,,n)
if(d[i]>=) flag=;
if(!flag)
{
printf("-1\n");
return ;
}
dfs(,);
print();
return ;
}
实际上只有1条或者2条从1下来的链,枚举1和与1相邻的颜色然后就能推出整条链
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 200010
#define M 200010
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const ll MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
ll INF=1e15;
int da[]={-,,,};
int db[]={,,-,}; struct node
{
int x,y;
}pre[N][][]; ll a[N][];
int head[N],vet[N],nxt[N],f[N],g[N],b[N],c[N],d[N],p[N],tot,son; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b)
{
nxt[++tot]=head[a];
vet[tot]=b;
head[a]=tot;
} void dfs(int u,int fa)
{
int e=head[u];
while(e)
{
int v=vet[e];
if(v!=fa)
{
f[v]=u;
g[u]=v;
if(u==)
{
son++;
p[son]=v;
}
dfs(v,u);
}
e=nxt[e];
}
} int main()
{
//freopen("1.in","r",stdin);
int n=read();
rep(j,,)
rep(i,,n) scanf("%I64d",&a[i][j]);
rep(i,,n) head[i]=d[i]=;
tot=;
rep(i,,n-)
{
int x=read(),y=read();
add(x,y);
add(y,x);
d[x]++; d[y]++;
}
int flag=;
rep(i,,n)
if(d[i]>=) flag=;
if(!flag)
{
printf("-1\n");
return ;
}
son=;
dfs(,);
ll ans=INF;
if(son==)
{
rep(x,,)
{
int u=p[];
rep(y,,)
if(x!=y)
{
b[]=x; b[u]=y;
int k=u;
while(k)
{
k=g[k];
if(!k) break;
b[k]=-b[f[k]]-b[f[f[k]]];
}
ll s=;
rep(i,,n) s+=a[i][b[i]];
if(s<ans)
{
ans=s;
rep(i,,n) c[i]=b[i];
}
}
}
}
else
{
int u1=p[],u2=p[];
rep(x,,)
rep(y,,)
rep(z,,)
if(x!=y&&x!=z&&y!=z)
{
b[]=x; b[u1]=y;
int k=u1;
while(k)
{
k=g[k];
if(!k) break;
b[k]=-b[f[k]]-b[f[f[k]]];
}
b[u2]=z;
k=u2;
while(k)
{
k=g[k];
if(!k) break;
b[k]=-b[f[k]]-b[f[f[k]]];
}
ll s=;
rep(i,,n) s+=a[i][b[i]];
if(s<ans)
{
ans=s;
rep(i,,n) c[i]=b[i];
}
}
} printf("%I64d\n",ans);
rep(i,,n) printf("%d ",c[i]+);
return ;
}
【CF1244D】Paint the Tree(树形DP,树)的更多相关文章
- E. Paint the Tree 树形dp
E. Paint the Tree 题目大意:给你一棵树,每一个点都可以染k种颜色,你拥有无数种颜色,每一种颜色最多使用2次,如果一条边的两个节点拥有同一种颜色,那么就说 这条边是饱和的,一个树的价值 ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- 树形DP+树状数组 HDU 5877 Weak Pair
//树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...
- 熟练剖分(tree) 树形DP
熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...
- hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
/** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...
- CF 461B Appleman and Tree 树形DP
Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other ...
- codeforces 161D Distance in Tree 树形dp
题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...
- POJ 1655.Balancing Act 树形dp 树的重心
Balancing Act Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14550 Accepted: 6173 De ...
- 5.10 省选模拟赛 tree 树形dp 逆元
LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...
- hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)
题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others) Memory Limit: ...
随机推荐
- 《图解设计模式》读书笔记7-1 facade模式
目录 1. Facade模式简介 2. 示例程序 2.1 类图 2.2 程序 3.角色和类图 4.思路拓展 1. Facade模式简介 开发程序的过程中,随着时间的推移,类会越来越多,调用关系会越来越 ...
- 测开之路一百一十三:bootstrap媒体对象
实现效果,左边是图片或者其他媒体,右边是对应的描述 引入bootstrap和jquery标签 class="media" 数量多一些看着就会很规整 <!DOCTYPE htm ...
- clientdataset 读取excel 如果excel 文件不存在的时候 相应的gird 会不显示数据, 鼠标掠过 gird 格子 才会显示数据。 这是一个bug 哈哈
clientdataset 读取excel 如果excel 文件不存在的时候 相应的gird 会不显示数据, 鼠标掠过 gird 格子 才会显示数据. 这是一个bug 哈哈
- linux环境,centos7,安装docker
https://www.jianshu.com/p/2dae7b13ce2f 1.安装依赖包 yum install -y yum-utils device-mapper-persistent-dat ...
- Git的资源地址
下载地址:https://git-scm.com/downloads 安装教程: https://baijiahao.baidu.com/s?id=1619087367741781687&wf ...
- Temporal-Difference Learning for Prediction
In Monte Carlo Learning, we've got the estimation of value function: Gt is the episode return from t ...
- python+selenium下拉列表option对象操作方法一
参考官方文档:https://selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.select ...
- python基础-7.3模块 configparser logging subprocess os.system shutil
1. configparser模块 configparser用于处理特定格式的文件,其本质上是利用open来操作文件. 继承至2版本 ConfigParser,实现了更多智能特征,实现更有可预见性,新 ...
- Sentinel整合Dubbo限流实战(分布式限流)
之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...
- JAVA总结--java数据类型
一.String 1.String定义是指向堆内存中的引用:String的赋值本身是引用对象的切换,切换前后的对象依然存在:源码为:private final char value[]: 2.对多个S ...