洛谷——P3914 染色计数
P3914 染色计数
题目描述
有一颗NN个节点的树,节点用1,2,\cdots,N1,2,⋯,N编号。你要给它染色,使得相邻节点的颜色不同。有MM种颜色,用1,2,\cdots,M1,2,⋯,M编号。每个节点可以染MM种颜色中的若干种,求不同染色方案的数量除以(10^9 + 7109+7)的余数。
输入输出格式
输入格式:
第1 行,2 个整数N,MN,M。
接下来NN行,第ii行表示节点ii可以染的颜色。第1个整数k_iki,表示可以染的颜色数量。接下来k_iki个整数,表示可以染的颜色编号。
最后N - 1N−1行,每行2个整数A_i,B_iAi,Bi,表示边(A_i,B_i)(Ai,Bi)。
输出格式:
1 个整数,表示所有的数。
输入输出样例
说明
• 对于30% 的数据,1 \le N \le 10; 1 \le M \le 41≤N≤10;1≤M≤4;
• 对于60% 的数据,1 \le N \le 200; 1 \le M \le 2001≤N≤200;1≤M≤200;
• 对于100% 的数据,1 \le N \le 5000; 1 \le M \le 50001≤N≤5000;1≤M≤5000。
dfs+组合数学 爆零、、(可能是我写的问题)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 5100
#define LL long long
#define mod 1000000007
using namespace std;
long long ans;
bool vis[N],vist[N],boo[N][N];
int n,m,x,y,tot,k[N],head[N],a[N][N],same[N][N];
int read()
{
,f=; char ch=getchar();
;ch=getchar();}
+ch-',ch=getchar();
return x*f;
}
struct Edge
{
int to,next;
}edge[N];
int add(int x,int y)
{
tot++;
edge[tot].to=y;
edge[tot].next=head[x];
head[x]=tot;
}
int dfs(int x)
{
for(int i=head[x];i;i=edge[i].next)
{
int t=edge[i].to;
if(!vis[t])
{
vis[t]=true;
if(!vist[t])
{
vist[t]=true;
ans=(ans%mod+1ll*(k[x]-same[x][t])*k[t]%mod+(1ll*same[x][t]*(k[t]-)%mod))%mod;
}
dfs(t);
vis[t]=false;
}
}
}
int main()
{
n=read(),m=read();
;i<=n;i++)
{
k[i]=read();
;j<=k[i];j++)
a[i][j]=read(),boo[i][a[i][j]]=true;
}
;i<n;i++)
{
x=read(),y=read();
add(x,y),add(y,x);
;j<=k[y];j++)
if(boo[x][a[y][j]])
same[x][y]++,same[y][x]++;
}
vist[]=);
printf("%lld",ans);
;
}
0分代码
不会做了,粘个题解
令f[i][j]f[i][j]表示以ii为根的这棵子树在ii为颜色jj的时候的方案数,根据乘法原理可得f[i][j]=πf[k][c]f[i][j]=πf[k][c] 其中kk是ii的所有儿子,cc是所有与jj不同的颜色。
因此我们可以很容易相处一个O(n^3)O(n3)的是算法:枚举所有点,枚举它的颜色,枚举每一个儿子,枚举儿子的颜色,因为一个点只有一个父亲,所以枚举儿子的那一层加上枚举每一个点一共是O(n)O(n)的。
回过头来再看数据n<=5000n<=5000,m<=5000m<=5000,上述的算法似乎运行起来很吃力。那我们需要向一个办法去将复杂度变成O(n^2)O(n2),仔细思考后我们会发现,其实枚举儿子那一层是没有必要的,因为我只要颜色不相同的总数,与其O(m)O(m)地去求和,不如之前在枚举到它的时候就处理好所有的和,然后O(1)O(1)地去剪掉这个颜色,从而求出除去这个颜色外的方案数,达到O(n^2)O(n2)的复杂度。
这道题还是很不错的,这种思想在很多时候都能用得上。
# include <algorithm>
# include <iostream>
# include <cstring>
# include <cstdio>
# include <vector>
# include <cmath>
# define R register
# define mod
using namespace std;
][],h[],tot[],sum[],x,y,d;
];
inline void in(R int &a){
R , f=;
; c = getchar();}
)+(x<<)+c-',c = getchar();
a=x*f;
}
inline void add(R int x,R int y){
ed[++e] = (pp){y,h[x]};
h[x] = e;
}
inline void dfs(R int fa,R int x){//树形DP一般用DFS来实现
for(R int i=h[x]; i; i=ed[i].pre)
{
R int p = ed[i].v;
if(p == fa) continue;
dfs(x,p);
}
; j<=m; ++j)
{
if(!f[x][j]) continue;//没有这种颜色
for(R int i=h[x]; i; i=ed[i].pre)
{
R int p = ed[i].v;
if(p == fa) continue;
f[x][j] = 1LL*f[x][j]*(tot[p]-f[p][j])%mod;
}
) f[x][j] += mod;//上边(tot[p]-f[p][j])可能会变成负数,这里把它变回来。
tot[x] = (1LL*tot[x]+1LL*f[x][j])%mod;
}
}
inline int yg(){
in(n),in(m);
; i<=n; ++i)
{
in(sum[i]);
; j<=sum[i]; ++j) in(d),f[i][d]++;
}
; i<n; ++i)
{
in(x),in(y);
add(x,y),add(y,x);
}
add(,);//为了好写,新建一个原点连向1,这样就不用额外求tot[1]了
dfs(,);
cout << tot[];//tot[1]就是最终的答案
}
int youngsc = yg();
int main(){;}
洛谷——P3914 染色计数的更多相关文章
- 洛谷 P3914 染色计数
P3914 染色计数 题目描述 有一颗NN个节点的树,节点用1,2,\cdots,N1,2,⋯,N编号.你要给它染色,使得相邻节点的颜色不同.有MM种颜色,用1,2,\cdots,M1,2,⋯,M编号 ...
- 洛谷P1144-最短路计数-最短路变形
洛谷P1144-最短路计数 题目描述: 给出一个\(N\)个顶点\(M\)条边的无向无权图,顶点编号为\(1-N\).问从顶点\(1\)开始,到其他每个点的最短路有几条. 思路: \(Dijkstra ...
- 洛谷P2486 染色
LCT的一种姿势. 题意:给定一棵树.每次把一条路径上的点染成一种颜色,求一条路径上有多少段颜色. 解: 首先可以很轻易的用树剖解决,只不过代码量让人望而却步... 有一种难以想象的LCT做法... ...
- 洛谷——P1176 路径计数2
P1176 路径计数2 题目描述 一个N \times NN×N的网格,你一开始在(1,1)(1,1),即左上角.每次只能移动到下方相邻的格子或者右方相邻的格子,问到达(N,N)(N,N),即右下角有 ...
- 洛谷 P1176 路径计数2
P1176 路径计数2 题目描述 一个N×N的网格,你一开始在(1, 1),即左上角.每次只能移动到下方相邻的格子或者右方相邻的格子,问到达(N, N),即右下角有多少种方法. 但是这个问题太简单了, ...
- 洛谷 P3130 [USACO15DEC]计数haybalesCounting Haybales
P3130 [USACO15DEC]计数haybalesCounting Haybales 题目描述 Farmer John is trying to hire contractors to help ...
- 洛谷 P2807 三角形计数
P2807 三角形计数 题目背景 三角形计数(triangle) 递推 题目描述 把大三角形的每条边n等分,将对应的等分点连接起来(连接线分别平行于三条边),这样一共会有多少三角形呢?编程来解决这个问 ...
- 洛谷P1608 路径计数
题目简介 题目描述 给你一个N点M边的有向图,求第一个点到第n个点的最短路和最短路条数 题目分析 很明显直接Dijkstra求最短路,加一个最短路计数 如下: if(dis[y]>dis[x]+ ...
- P3914染色计数
题目描述 有一颗\(N\)个节点的树,节点用\(1,2,\cdots,N\)编号.你要给它染色,使得相邻节点的颜色不同.有\(M\)种颜色,用\(1,2,\cdots,M\)编号.每个节点可以染\(M ...
随机推荐
- 【ZJ选讲·BZOJ 5071】
小A的数字 有一串数字A1 ,A2,--,An,每次可以进行如下骚操作: 选择一个数字i,将(Ai-1,Ai,Ai+1)变为(Ai-1+Ai,-Ai,Ai+1+Ai), (特别地,若i=N,则( ...
- codeforces 799C Fountains
C. Fountains time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- 解决“并非来自 Chrome 网上应用店。”
Chrome谷歌浏览器已停用不支持的扩展程序解决方法 第一种方法:(亲测有效) 1.首先把需要安装的第三方插件,后缀.crx 改成 .rar,然后解压,得到一个文件夹 2.再打开chrome://ex ...
- Ubuntu 编译Webkit --gtk
转载自:http://www.linuxidc.com/Linux/2011-10/44809.htm webkit是一个浏览器内核,google的chrome就是基于它的,下面介绍一下如何在Ubun ...
- Python 入门学习笔记
安装和运行 官网下载安装包https://www.python.org/downloads/mac-osx/下载完直接安装即可 运行打开 terminal,输入命令 python,进入 python ...
- 转:安装成功的nginx如何添加未编译安装模块
原已经安装好的nginx,现在需要添加一个未被编译安装的模块 举例说明:安装第三方的ngx_cache_purge模块(用于清除指定URL的缓存) nginx的模块是需要重新编译nginx,而不是像a ...
- Spring 学习笔记(二)
一.Spring 中的bean配置 –配置形式:基于 XML 文件的方式:基于注解的方式 –Bean 的配置方式:通过全类名(反射).通过工厂方法(静态工厂方法 & 实例工厂方法).Fac ...
- Javadoc注释的用法
Javadoc注释的用法 相关阅读:http://blog.163.com/hui_san/blog/static/5710286720104191100389/ Java 文档// 注释一行/* ...
- bzoj 2748 DP
比较裸的背包,w[i][j]代表到第I个操作的时候音量j能不能达到,然后转移就行了. /******************************************************** ...
- CVE-2016-6662 利用条件
首先执行SET GLOBAL 需要超级用户权限,所以利用条件要么用户本身是超级用户要么用户有trigger权限,通过创建trigger,由超级用户触发SET GLOBAL. 然而MYsql有个通过fi ...