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