题意:

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,树)的更多相关文章

  1. E. Paint the Tree 树形dp

    E. Paint the Tree 题目大意:给你一棵树,每一个点都可以染k种颜色,你拥有无数种颜色,每一种颜色最多使用2次,如果一条边的两个节点拥有同一种颜色,那么就说 这条边是饱和的,一个树的价值 ...

  2. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  3. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  4. 熟练剖分(tree) 树形DP

    熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...

  5. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  6. 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 ...

  7. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

  8. POJ 1655.Balancing Act 树形dp 树的重心

    Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14550   Accepted: 6173 De ...

  9. 5.10 省选模拟赛 tree 树形dp 逆元

    LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...

  10. 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: ...

随机推荐

  1. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_3_字节输出流_OutputStream类&FileOutputStream

    都在IO包下 所有字节输出最顶层的父类 它是一个抽象类.abstract修饰的 一般这种类定义的都是所有字节流都可以使用公共的方法,

  2. unique()函数

    unique()函数可输出列表,元组和series中的不同元素. 且只能输出dataframe的某一列series中的不同元素,不能同时输出. 返回的都是一个ndarry,但不能输出ndarry中的不 ...

  3. servlet过滤器Filter使用之DelegatingFilterProxy类

    正常情况下,我们需要添加一个过滤器,需要实现javax.servlet.Filter接口,再在web.xml中配置filter,如下: package cc.eabour.webapp.securit ...

  4. 字符串中的TOUPPER函数

    std::string& str_toupper(std::string& s) { std::transform(s.begin(), s.end(), s.begin(), []( ...

  5. MVC 源码系列之控制器执行(二)

    ## 控制器的执行 上一节说道Controller中的ActionInvoker.InvokeAction public virtual bool InvokeAction(ControllerCon ...

  6. 【MM系列】SAP MM中物料帐下修改物料的价格

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP 物料帐下修改物料的价格   ...

  7. linux下安装python27 nginx 和uwsgi

    注意: python27 默认没有安装 pip 和setuptools所以要提前安装.(务必先提前安装python27 哈 ) wget --no-check-certificate https:// ...

  8. dataTables使用的详细说明整理

    本文共三个部分:官网|基本使用|遇到的问题 一.官方网站:http://www.datatables.club/ 二.基本使用: 1.dataTables的引入及初始化 <!--第一步:引入Ja ...

  9. markDown 生成带侧边栏的目录

    1.首先安装马克飞象 2.第二步安装 npm install -g i5ting_toc 3.进入 md 文件所在的文件夹后, 输入命令:   i5ting_toc -f sample.md -o s ...

  10. Linux 重定向命令有哪些?有什么区别?

    1.重定向>Linux 允许将命令执行结果重定向到一个文件,本应显示在终端上的内容保存到指定文件中.如:ls >test.txt ( test.txt 如果不存在,则创建,存在则覆盖其内容 ...