题目大意:
  给定一个$n(n\le20000)$条个点,$m(m\le25000)$条边的无向图,保证图中最长路径上的点数不超过$10$。对一个点染色的代价是$w_i$。求使得每个结点都被染色或至少有一个相邻结点被染色的最小代价。

思路:
  由于图中最长路径上的点数不超过$10$,也就是说,对于每一个联通块的任一生成树,其最深结点的深度不超过$10$。考虑三进制状压DP,用$f[i][j]$表示深度为$i$的点,前$i$个深度状态为$j$的最小代价。其中每个状态的第$k$位为$0$则深度为$k$的结点已染色,若为$1$则表示未染色且相邻点也没有染色,若为$2$则表示未染色但是相邻结点有染色。搜索完一棵子树后将状态上传到父结点。

 #include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,M=,K=,S=;
const int pow[]={,,,,,,,,,,};
bool vis[N];
int w[N],dep[N],h[N],sz;
unsigned f[K][S];
struct Edge {
int to,next;
};
Edge e[M];
inline void add_edge(const int &u,const int &v) {
e[++sz]=(Edge){v,h[u]};h[u]=sz;
e[++sz]=(Edge){u,h[v]};h[v]=sz;
}
inline int bit(const int &x,const int &k) {
return x/pow[k]%;
}
void dfs(const int &x,const int &d) {
vis[x]=true;
if((dep[x]=d)==) {
f[][]=w[x];
f[][]=;
f[][]=INT_MAX;
} else {
std::fill(&f[d][],&f[d][pow[d+]],INT_MAX);
for(register int i=,j=;i<pow[d];j=++i) {
int b=;
for(register int k=h[x];k;k=e[k].next) {
const int &y=e[k].to;
if(!vis[y]||dep[y]>=d) continue;
if(bit(i,dep[y])==) b=;
if(bit(i,dep[y])==) j+=pow[dep[y]];
}
f[d][i+b*pow[d]]=std::min(f[d][i+b*pow[d]],f[d-][i]);
f[d][j]=std::min(f[d][j],f[d-][i]+w[x]);
}
}
for(int i=h[x];i;i=e[i].next) {
const int &y=e[i].to;
if(vis[y]) continue;
dfs(y,d+);
for(register int i=;i<pow[d+];i++) {
f[d][i]=std::min(f[d+][i],f[d+][i+*pow[d+]]);
}
}
}
int main() {
const int n=getint(),m=getint();
for(register int i=;i<=n;i++) w[i]=getint();
for(register int i=;i<m;i++) {
add_edge(getint(),getint());
}
int ans=;
for(register int i=;i<=n;i++) {
if(vis[i]) continue;
dfs(i,);
ans+=std::min(f[][],f[][]);
}
printf("%d\n",ans);
return ;
}

最新文章

  1. JavaScript简单分页,兼容IE6,~3KB
  2. mybatis实战教程(mybatis in action),mybatis入门到精通
  3. 解决secureCRT数据库里没有找到防火墙 &#39;无&#39;问题
  4. 在线代码格式化,在线JSON校验格式化
  5. Sublime Text 插件列表(整理中...)
  6. OBIEE 11g:Error:nQSError 36010 Server version 318 cannot read the newer version of the repository
  7. Java这点事
  8. Adobe Flash Builder 4.7下载地址及破解补丁(32位&amp;64位)
  9. 检查string是否为double
  10. Ext.Ajax.request同步请求
  11. 最新版-MySQL8.0 安装 - 改密码 之坑
  12. mysql 函数学习(常用)
  13. *CTF 2019 quicksort、babyshell、upxofcpp
  14. XCTF体验题库 : ReverseMe-120
  15. HDU 1051(处理木棍 贪心)
  16. CentOS 7创建自定义KVM模板(现有KVM迁移到另外一台机)
  17. .NetCore下使用Prometheus实现系统监控和警报 (五)进阶自定义收集指标 之 Counter
  18. python environ PYTHON_EGG_CACHE
  19. Swift基础语法之变量函数
  20. QVariant相当于一个包含大多数Qt数据类型的联合体(源码解读)

热门文章

  1. python3知识点之---------列表的介绍
  2. python学习总结---面向对象1
  3. cookie换肤功能
  4. diskimage-builder element
  5. 课时46:魔法方法:描述符(property的原理)
  6. 团队项目-第七次scrum 会议
  7. excel模板解析—桥接模式:分离解析模板和业务校验
  8. Java获取当前服务器IP实现
  9. 使用pdb模块调试Python
  10. Dev express 笔记