bzoj 2595 [Wc2008]游览计划(斯坦纳树)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=2595
【题意】
给定N*M的长方形,选最少权值和的格子使得要求的K个点连通。
【科普】
“斯坦纳树”就是包含给定点的最小生成树。
【思路】
那么本题就是求一棵斯坦纳树。
设f[i][j][S]表示在点(i,j)且与之相连的点的状态为S。
有两种转移:
f[i][j][S]<-f[i][j][S’]+f[i][j][S-S’]-a[i][j],合并子集
f[i][j][S]<-f[i’][j’][S]+a[i][j],相邻点更新
第一种转移可能包含重点的情况,所以还需要第二种转移方程。
第一种转移可以直接枚举子集完成转移。
第二种转移的更新虽然会出现环的情况,但结果一定满足三角形不等式
f[i][j][S]<=f[i’][j’][S] +a[i][j]
所以可以用spfa算法求。
【代码】
- #include<set>
- #include<cmath>
- #include<queue>
- #include<vector>
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
- using namespace std;
- const int N = ;
- const int inf = 0xf0f0f0f;
- const int dx[]={,-,,};
- const int dy[]={,,,-};
- int n,m,K,st[N][N];
- int vis[N][N],a[N][N],f[N][N][<<N],pre[N][N][<<N];
- int pack(int i,int j) { return i*+j; }
- void unpack(int x,int& i,int& j) { i=x/,j=x%; }
- int pack2(int i,int j,int st) { return i*+j*+st; }
- void unpack2(int x,int& i,int& j,int& st) { st=x%,i=x/,j=(x/)%; }
- int upd(int i,int j,int s,int x,int y,int s2,int w)
- {
- if(f[i][j][s]>w) return f[i][j][s]=w,pre[i][j][s]=pack2(x,y,s2),;
- return ;
- }
- queue<int> q;
- int inq[N*N];
- void spfa(int sta)
- {
- while(!q.empty()) {
- int u=q.front(),i,j; q.pop();
- inq[u]=;
- unpack(u,i,j);
- FOR(k,,) {
- int x=i+dx[k],y=j+dy[k],tmp;
- if(x<||x>=n||y<||y>=m) continue;
- if(upd(x,y,sta,i,j,sta,f[i][j][sta]+a[x][y])&&(!inq[tmp=pack(x,y)])) {
- q.push(tmp),inq[tmp]=;
- }
- }
- }
- }
- void dfs(int i,int j,int st)
- {
- int x,y,nst;
- vis[i][j]=;
- if(!pre[i][j][st]) return ;
- unpack2(pre[i][j][st],x,y,nst);
- dfs(x,y,nst);
- if(x==i&&y==j) dfs(x,y,st-nst);
- }
- int main()
- {
- //freopen("trip.in","r",stdin);
- //freopen("trip.out","w",stdout);
- memset(f,0xf,sizeof(f));
- scanf("%d%d",&n,&m);
- FOR(i,,n-) FOR(j,,m-) {
- scanf("%d",&a[i][j]);
- if(!a[i][j]) st[i][j]=<<(K++),f[i][j][st[i][j]]=;
- }
- int all=(<<K),tmp;
- FOR(sta,,all-) {
- FOR(i,,n-) FOR(j,,m-) {
- for(int s=sta&(sta-);s;s=(s-)&sta)
- upd(i,j,sta,i,j,s,f[i][j][s]+f[i][j][sta-s]-a[i][j]);
- if(f[i][j][sta]!=inf) q.push(tmp=pack(i,j)),inq[tmp]=;
- }
- spfa(sta);
- }
- FOR(i,,n-) FOR(j,,m-) if(!a[i][j]) {
- printf("%d\n",f[i][j][all-]);
- dfs(i,j,all-);
- FOR(ii,,n-) {
- FOR(jj,,m-) {
- if(!a[ii][jj]) putchar('x');
- else if(vis[ii][jj]) putchar('o');
- else putchar('_');
- }
- puts("");
- }
- return ;
- }
- }
bzoj 2595 [Wc2008]游览计划(斯坦纳树)的更多相关文章
- BZOJ 2595 [Wc2008]游览计划 ——斯坦纳树
[题目分析] 斯坦纳树=子集DP+SPFA? 用来学习斯坦纳树的模板. 大概就是用二进制来表示树包含的点,然后用跟几点表示树的形态. 更新分为两种,一种是合并两个子集,一种是换根,换根用SPFA迭代即 ...
- 【BZOJ2595】[Wc2008]游览计划 斯坦纳树
[BZOJ2595][Wc2008]游览计划 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为 ...
- Luogu 4294 [WC2008]游览计划 | 斯坦纳树
题目链接 Luogu 4294 (我做这道题的时候BZOJ全站的SPJ都炸了 提交秒WA 幸好有洛谷) 题解 这道题是[斯坦纳树]的经典例题.斯坦纳树是这样一类问题:带边权无向图上有几个(一般约10个 ...
- bzoj2595: [Wc2008]游览计划 斯坦纳树
斯坦纳树是在一个图中选取某些特定点使其联通(可以选取额外的点),要求花费最小,最小生成树是斯坦纳树的一种特殊情况 我们用dp[i][j]来表示以i为根,和j状态是否和i联通,那么有 转移方程: dp[ ...
- bzoj2595 [Wc2008]游览计划——斯坦纳树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2595 今天刚学了斯坦纳树,还不太会,写一道题练习一下: 参考了博客:http://www.c ...
- BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)
Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 2030 Solved: 986[Submit][Status][ ...
- P4294 [WC2008]游览计划 (斯坦纳树)
题目链接 差不多是斯坦纳树裸题,不过边权化成了点权,这样在合并两棵子树时需要去掉根结点的权值,防止重复. 题目还要求输出解,只要在转移时记录下路径,然后dfs一遍就好了. #include<bi ...
- 洛谷4294 [WC2008]游览计划——斯坦纳树
题目:https://www.luogu.org/problemnew/show/P4294 大概是状压.两种转移,一个是以同一个点为中心,S由自己的子集拼起来:一个是S相同.中心不同的同层转移. 注 ...
- 【BZOJ-2595】游览计划 斯坦纳树
2595: [Wc2008]游览计划 Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 1518 Solved: 7 ...
随机推荐
- kmalloc/kfree,vmalloc/vfree函数用法和区别
http://blog.csdn.net/tigerjibo/article/details/6412881 kmalloc/kfree,vmalloc/vfree函数用法和区别 1.kmalloc ...
- linux下安装Apache(https) 服务器证书安装配置指南
一. 安装准备 1. 安装Openssl 要使Apache支持SSL,需要首先安装Openssl支持.推荐下载安装openssl-0.9.8k.tar.gz 下载Openssl:http: ...
- WCF入门(六)---主机WCF服务
建立一个WCF服务后,下一步就是托管它,以便客户端应用程序可以使用,这就是所谓的WCF服务托管. WCF服务可以通过使用任何的四种方法如下托管. IIS主机 - IIS是Internet信息服务的缩写 ...
- 2、JPA的HelloWorld
这一节写一个JPA的HelloWorld来体验一下. 一.建立工程 按照 1.创建一个JPA project(解决“at least one user library must be selected ...
- R语言日期时间函数
Sys.Date( ) returns today's date. date() returns the current date and time.# print today's datetoday ...
- [POJ1330]Nearest Common Ancestors(LCA, 离线tarjan)
题目链接:http://poj.org/problem?id=1330 题意就是求一组最近公共祖先,昨晚学了离线tarjan,今天来实现一下. 个人感觉tarjan算法是利用了dfs序和节点深度的关系 ...
- grunt + compass
compass和sass文章列表:http://182.92.240.72/tag/compass/ compass实战grunt: http://wrox.cn/article/2000491/ h ...
- POJ 2828 Buy Tickets (线段树 单点更新 变形)
题目链接 题意:有N个人排队,给出各个人想插队的位置和标识,要求输出最后的序列. 分析:因为之前的序列会因为插队而变化,如果直接算时间复杂度很高,所以可以用 线段树逆序插入,把序列都插到最后一层,le ...
- bzoj2432
被虐的体无完肤, 直接给题解地址吧:http://vfleaking.blog.163.com/blog/static/174807634201341721051604/ ; ..,..] of in ...
- 服务器发布MVC常见问题解决方案
1 问题:IIS上部署MVC网站,打开后500错误:处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelin ...