传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4006

思路:

一眼看上去很像斯坦纳树

但是限制稍有不同,只要每种颜色的点联通即可

也就是说最后可能是森林

我听说裸写斯坦纳树有90


所以我们要在外面再套一层DP

f[i][j]还是斯坦纳树的状态,i是以i为根,j是状态为j

先用斯坦纳树求出每种联通状况的最小费用

再设dp[i]表示i这个状态的最小费用

枚举子集时保证颜色相同的连通性相同,转移即可

dp[i]=min(dp[j]+dp[i-j])j是i的子集

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
const int maxn=11,maxk=11,maxq=105;
const int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
using namespace std;
int n,m,K,head,tail,cnt,pw[maxk+5],w[maxk],q[maxq+10],f[maxn][maxn][1<<maxk],pre[maxn][maxn][1<<maxk],a[maxn][maxn],inf;
bool bo[maxn][maxn],vis[maxn][maxn];
inline bool in(int x,int y){return x>=0&&x<n&&y>=0&&y<m;}
inline int id(int x,int y){return x*10+y;}
inline int id2(int x,int y,int s){return s*100+x*10+y;}
inline void decode(int sta,int &x,int &y){x=sta/10,y=sta%10;}
inline void decode2(int sta,int &x,int &y,int &s){s=sta/100,x=sta%100/10,y=sta%10;}void init(){pw[0]=1;for (int i=1;i<=11;i++) pw[i]=pw[i-1]<<1;scanf("%d%d",&n,&m);for (int i=0;i<n;i++)for (int j=0;j<m;j++){scanf("%d",&a[i][j]);if (!a[i][j]) w[K++]=id(i,j);}
}void spfa(int s){//printf("s=%d\n",s);while (head!=tail){if (++head>maxq) head=1;int sta=q[head],x,y;decode(sta,x,y);//printf("x=%d y=%d\n",x,y);for (int i=0;i<4;i++){int nx=x+dx[i],ny=y+dy[i];if (!in(nx,ny)) continue;//printf("nx=%d ny=%d\n",nx,ny);if (f[nx][ny][s]>f[x][y][s]+a[nx][ny]){f[nx][ny][s]=f[x][y][s]+a[nx][ny];//printf("ffffffffffffffffffffffffffffff=%d\n",f[nx][ny][s]);pre[nx][ny][s]=id2(x,y,s);if (!bo[nx][ny]){if (++tail>maxq) tail=1;bo[nx][ny]=1,q[tail]=id(nx,ny);}}}bo[x][y]=0;}
}void dfs(int i,int s){int x,y,nx,ny,t;decode(i,x,y);//printf("x=%d y=%d s=%d\n",x,y,s);vis[x][y]=1;if (!pre[x][y][s]) return;//printf("%d %d\n",id2(x,y,s),pre[x][y][s]);decode2(pre[x][y][s],nx,ny,t);//printf("px=%d py=%d pt=%d\n",nx,ny,t);dfs(id(nx,ny),t);if (x==nx&&y==ny) dfs(id(nx,ny),s^t);
}void work(){memset(f,63,sizeof(f)),inf=f[0][0][0];for (int i=0,x,y;i<K;i++){decode(w[i],x,y);f[x][y][pw[i]]=0;}for (int sta=1;sta<pw[K];sta++){head=tail=0;for (int i=0;i<n;i++)for (int j=0;j<m;j++){for (int s=sta&(sta-1);s;s=(s-1)&sta)if (f[i][j][sta]>f[i][j][s]+f[i][j][sta^s]-a[i][j]){f[i][j][sta]=f[i][j][s]+f[i][j][sta^s]-a[i][j];pre[i][j][sta]=id2(i,j,s);}if (f[i][j][sta]!=inf) q[++tail]=id(i,j),bo[i][j]=1;//printf("x=%d y=%d sta=%d f=%d\n",i,j,sta,f[i][j][sta]);}spfa(sta);}int x,y;decode(w[0],x,y);//printf("xx=%d yy=%d sta=%d\n",x,y,pw[K]-1);printf("%d\n",f[x][y][pw[K]-1]);int nx,ny,ns;decode2(pre[x][y][pw[K]-1],nx,ny,ns);//printf("nx=%d ny=%d ns=%d\n",nx,ny,ns);dfs(w[0],pw[K]-1);for (int i=0;i<n;i++,puts(""))for (int j=0;j<m;j++)if (!a[i][j]) putchar('x');else if (vis[i][j]) putchar('o');else putchar('_');
}int main(){//freopen("test.in","r",stdin);freopen("test.out","w",stdout);init(),work();return 0;
}
/*
8 8
1 4 1 3 4 2 4 1
4 3 1 2 0 1 2 3
3 2 1 3 0 3 1 2
2 6 5 0 2 4 1 0
5 1 2 1 3 4 2 5
5 1 3 1 5 0 1 4
5 0 6 1 4 5 3 4
0 2 2 2 3 4 1 1*/

转载于:https://www.cnblogs.com/thythy/p/5493626.html

bzoj4006: [JLOI2015]管道连接相关推荐

  1. [bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp

    管道连接 bzoj-4006 JLOI-2015 题目大意:给定一张$n$个节点$m$条边的带边权无向图.并且给定$p$个重要节点,每个重要节点都有一个颜色.求一个边权和最小的边集使得颜色相同的重要节 ...

  2. [JLOI2015]管道连接(斯坦纳树)

    [Luogu3264] 原题解 多个频道,每个频道的关键点要求相互联通 详见代码,非常巧妙 #include<cstdio> #include<iostream> #inclu ...

  3. BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)

    题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...

  4. 解决:未能将管道连接到虚拟机: 所有的管道范例都在使用中。

    虚拟机无端出现: VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使用的所有目录以及访问所有临时文件目录.未能将管道连接到虚拟机: 所有的管道范例都在使用中 ...

  5. 未能将管道连接到虚拟机: 所有的管道范例都在使用中

    强行关闭虚拟机会经常出现: VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使用的所有目录以及访问所有临时文件目录.未能将管道连接到虚拟机: 所有的管道范例 ...

  6. VMware解决:未能将管道连接到虚拟机: 所有的管道范例都在使用中。

    VMware Workstation 无法连接到虚拟机 请确保您有权运行该程序 访问该程序使用的所有目录以及访问所有临时文件目录. 未能将管道连接到虚拟机: 所有的管道范例都在使用中. 由于上一次使用 ...

  7. VMware Workstation 无法连接到虚拟机。请确保您有权限运行该程序、访问改程序使用的所有目录以及访问所有临时文件目录。未能将管道连接到虚拟机: 所有的管道范例都在使用中。

    现象: 虚拟机无端出现,VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使用的所有目录以及访问所有临时文件目录.未能将管道连接到虚拟机: 所有的管道范例都在 ...

  8. 虚拟机无端出现 未能将管道连接到虚拟机: 所有的管道范例都在使用中

    情景 VMware 卡住了.用任务管理器 强行结束了VMware 再次打开镜像的时候发生 虚拟机无端出现,VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使 ...

  9. DM7全库备份失败报错“管道连接超时”处理流程

    对DM7做全量备份,备份名为dmdb1.bak,通过命令和管理用具均备份失败 (1)通过命令进行全量备份 输入: backup database full backupset '/dm7/backup ...

最新文章

  1. NVIDIA Jarvis:一个GPU加速对话人工智能应用的框架
  2. 扔掉源码,15张图带你彻底理解java AQS
  3. 每天5道面试题(二)java基础
  4. 【福利贴】拿去!1024凑个整!
  5. 点运算符(.)和中括号运算符([])有哪些区别
  6. wine和steam的区别
  7. 电脑技巧:C盘爆满该如何清理,实用的清理方案,小白必备
  8. 鸿蒙系统6月可升级,华为鸿蒙2.0系统大规模升级从6月开始?
  9. jqgrid 批量启动所有行为可编辑状态
  10. 关于Android sdkmanager目录结构的总结
  11. 数据仓库项目管理面试题整理(十二)
  12. 1. jQuery 简介
  13. tensorflow学习笔记(3)梯度下降法进行曲线拟合和线性回归
  14. astgo-官方功能更新日志
  15. html中如何设置艺术字体,html里怎么把字体变成艺术字
  16. sierpinski三角形的维数_分形维数算法
  17. 工业相机基本参数以及选型
  18. cannot find -lnl
  19. TIA博途中通过关键字AT实现变量覆盖的具体方法及示例程序
  20. IBM沃森会成为第一个被抛弃的AI技术吗?

热门文章

  1. Prima Cartoonizer中文版
  2. wget的url获取方式
  3. java多线程3.设计线程安全类
  4. Vim YouCompleteMe 安装配置
  5. Ubuntu 进入、退出命令行的快捷键
  6. C# 调用 taskkill命令结束服务进程
  7. CodeForces 508E Arthur and Brackets 贪心
  8. SASS初学者入门(转)
  9. 理解这几张图,你就是js小牛了
  10. 特征点的基本概念和如何找到它们