bzoj4006: [JLOI2015]管道连接
传送门: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]管道连接相关推荐
- [bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp
管道连接 bzoj-4006 JLOI-2015 题目大意:给定一张$n$个节点$m$条边的带边权无向图.并且给定$p$个重要节点,每个重要节点都有一个颜色.求一个边权和最小的边集使得颜色相同的重要节 ...
- [JLOI2015]管道连接(斯坦纳树)
[Luogu3264] 原题解 多个频道,每个频道的关键点要求相互联通 详见代码,非常巧妙 #include<cstdio> #include<iostream> #inclu ...
- BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)
题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...
- 解决:未能将管道连接到虚拟机: 所有的管道范例都在使用中。
虚拟机无端出现: VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使用的所有目录以及访问所有临时文件目录.未能将管道连接到虚拟机: 所有的管道范例都在使用中 ...
- 未能将管道连接到虚拟机: 所有的管道范例都在使用中
强行关闭虚拟机会经常出现: VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使用的所有目录以及访问所有临时文件目录.未能将管道连接到虚拟机: 所有的管道范例 ...
- VMware解决:未能将管道连接到虚拟机: 所有的管道范例都在使用中。
VMware Workstation 无法连接到虚拟机 请确保您有权运行该程序 访问该程序使用的所有目录以及访问所有临时文件目录. 未能将管道连接到虚拟机: 所有的管道范例都在使用中. 由于上一次使用 ...
- VMware Workstation 无法连接到虚拟机。请确保您有权限运行该程序、访问改程序使用的所有目录以及访问所有临时文件目录。未能将管道连接到虚拟机: 所有的管道范例都在使用中。
现象: 虚拟机无端出现,VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使用的所有目录以及访问所有临时文件目录.未能将管道连接到虚拟机: 所有的管道范例都在 ...
- 虚拟机无端出现 未能将管道连接到虚拟机: 所有的管道范例都在使用中
情景 VMware 卡住了.用任务管理器 强行结束了VMware 再次打开镜像的时候发生 虚拟机无端出现,VMware Workstation 无法连接到虚拟机.请确保您有权限运行该程序.访问改程序使 ...
- DM7全库备份失败报错“管道连接超时”处理流程
对DM7做全量备份,备份名为dmdb1.bak,通过命令和管理用具均备份失败 (1)通过命令进行全量备份 输入: backup database full backupset '/dm7/backup ...
最新文章
- NVIDIA Jarvis:一个GPU加速对话人工智能应用的框架
- 扔掉源码,15张图带你彻底理解java AQS
- 每天5道面试题(二)java基础
- 【福利贴】拿去!1024凑个整!
- 点运算符(.)和中括号运算符([])有哪些区别
- wine和steam的区别
- 电脑技巧:C盘爆满该如何清理,实用的清理方案,小白必备
- 鸿蒙系统6月可升级,华为鸿蒙2.0系统大规模升级从6月开始?
- jqgrid 批量启动所有行为可编辑状态
- 关于Android sdkmanager目录结构的总结
- 数据仓库项目管理面试题整理(十二)
- 1. jQuery 简介
- tensorflow学习笔记(3)梯度下降法进行曲线拟合和线性回归
- astgo-官方功能更新日志
- html中如何设置艺术字体,html里怎么把字体变成艺术字
- sierpinski三角形的维数_分形维数算法
- 工业相机基本参数以及选型
- cannot find -lnl
- TIA博途中通过关键字AT实现变量覆盖的具体方法及示例程序
- IBM沃森会成为第一个被抛弃的AI技术吗?