【CodeChef】Find a special connected block - CONNECT(斯坦纳树)
【CodeChef】Find a special connected block - CONNECT(斯坦纳树)
题面
题解
还是一样的套路题,把每个数字映射到\([0,K)\)的整数,然后跑斯坦纳树,重复多次就有很大概率出解。
但是别乱随机,我直接随机\(WA\)成sb了,后来学了别人代码用自己手写的伪随机数就过了。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define ll long long
#define MAX 16
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
map<int,int> M;
int n,m,K,ans=2e9;
int a[MAX*MAX],b[MAX*MAX],c[MAX*MAX];
int f[1<<7][MAX*MAX];
queue<int> Q;bool vis[MAX*MAX];
vector<int> E[MAX*MAX];
int ID(int x,int y){return (x-1)*m+y;}
int d[4][2]={-1,0,0,-1,1,0,0,1};
void SPFA(int S)
{
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int v:E[u])
if(f[S][v]>f[S][u]+b[v])
{
f[S][v]=f[S][u]+b[v];
if(!vis[v]&&f[S][v]<=ans)vis[v]=true,Q.push(v);
}
vis[u]=false;
}
}
unsigned int Rand()
{
static unsigned int x=19260817;
x^=(x<<5);x^=(x>>17);x^=(x<<13);
return x;
}
int main()
{
n=read();m=read();K=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)a[ID(i,j)]=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)b[ID(i,j)]=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(~a[ID(i,j)])
for(int k=0;k<4;++k)
{
int x=i+d[k][0],y=j+d[k][1];
if(x<1||y<1||x>n||y>m||a[ID(i,j)]==-1)continue;
E[ID(i,j)].push_back(ID(x,y));
}
for(int Tim=1;Tim<=500;++Tim)
{
M.clear();
for(int i=1;i<=n*m;++i)
if(~a[i])
{
if(!M.count(a[i]))M[a[i]]=Rand()%K;
c[i]=M[a[i]];
}
memset(f,63,sizeof(f));
for(int i=1;i<=n*m;++i)if(~a[i])f[a[i]?(1<<c[i]):0][i]=b[i];
for(int S=0;S<(1<<K);++S)
{
for(int i=1;i<=n*m;++i)
{
if(a[i]==-1)continue;
for(int T=(S-1)&S;T;T=(T-1)&S)
f[S][i]=min(f[S][i],f[T][i]+f[S^T][i]-b[i]);
if(f[S][i]<=ans)Q.push(i),vis[i]=true;
}
SPFA(S);
}
for(int i=1;i<=n*m;++i)if(~a[i])ans=min(ans,f[(1<<K)-1][i]);
}
printf("%d\n",(ans>1e9)?-1:ans);
return 0;
}
【CodeChef】Find a special connected block - CONNECT(斯坦纳树)的更多相关文章
- BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)
Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 2030 Solved: 986[Submit][Status][ ...
- 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)
2595: [Wc2008]游览计划 Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 1572 Solved: 7 ...
- 【BZOJ2595】游览计划(状压DP,斯坦纳树)
题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...
- HDU 4085 斯坦纳树
题目大意: 给定无向图,让前k个点都能到达后k个点(保护地)中的一个,而且前k个点每个需要占据后k个中的一个,相互不冲突 找到实现这个条件达到的选择边的最小总权值 这里很容易看出,最后选到的边不保证整 ...
- hdu4085 Peach Blossom Spring 斯坦纳树,状态dp
(1)集合中元素表示(1<<i), i从0开始 (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s ...
- hdu 3311 斯坦纳树
思路:虚拟一个0号节点,将每个点建一条到0号节点的边,权值为挖井需要的价值.并要保证0号节点同另外n个寺庙一样被选择即可. 然后就是求斯坦纳树了. #include<map> #inclu ...
- HDU 3311 Dig The Wells(斯坦纳树)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3311 [题意] 给定k座庙,n个其他点,m条边,点权代表挖井费用,边权代表连边费用,问使得k座庙里 ...
- bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...
- bzoj 2595 [Wc2008]游览计划(斯坦纳树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...
随机推荐
- [C]#include和链接
概述 对于刚接触C语言的同学来说,通常对“在文件中用#include预处理操作符引入文件”和“编译时链接多个文件”这两个操作会有所混淆,这个文章主要为了解析一下它们的区别. #include预处理操作 ...
- Ubuntu18.04 设置开机进入命令行模式
首先来了解下启动级别(Runlevel): 指 Unix 或 类 Unix 操作系统下不同的运行模式,运行级别通常分为 7 级: 运行级别 0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启 ...
- linux自建https证书
一.生成单向认证的https证书 建立服务器私钥,生成RSA秘钥. 会有两次要求输入密码, 然后获得了一个server.key文件. 以后使用此文件(通过openssl提供的命令或API)可能经常回要 ...
- SpringCloud微服务(01):Eureka组件,管理服务注册与发现
本文源码:GitHub·点这里 || GitEE·点这里 一.Eureka基本架构 1.Eureka简介 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,SpringCl ...
- Java题库——chapter7 多维数组
1)Which of the following statements are correct? 1) _______ A)char[ ][ ] charArray = {{'a', 'b'}, {' ...
- PHP安全之道学习笔记4:系统命令注入
系统命令注入 我们有时候写代码会用php脚本去调用系统函数完成业务功能,但是一些系统函数属于高危操作,一旦被webshell或者抓住漏洞则后患极大. 下面整理如下风险系统函数. exec() 函数 该 ...
- Go-数据类型以及变量,常量
一.数据类型 1.字符串类型 string 2.数字类型 有符号整型: int: int 在32位机器上是int32 在64位机器是int64 int8: int8 表示数字范围是 正负2的7次方减1 ...
- 高强度学习训练第十四天总结:HashMap
HashMap 简介 HashMap 主要用来存放键值对,它基于哈希表的Map接口实现,是常用的Java集合之一. JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap ...
- 【JS基础语法】---学习roadmap---6 parts
JS基础语法---roadmap Part 1 - 2: Part 3 - 4: Part 5 - 6
- OC深浅复制
浅复制:指针的复制 深复制:内容的复制 主要有两个关键字 copy 和mutablecopy 对于基本类型 判断深浅方法 1.只要=右边从创建到赋值,至少包含一个NSMutable便会重新生成一个对 ...