【CodeChef】Find a special connected block - CONNECT(斯坦纳树)

题面

Vjudge

题解

还是一样的套路题,把每个数字映射到\([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;
}

最新文章

  1. win10调用局域网内xp系统上的打印机
  2. 基于Token的身份验证——JWT
  3. NeuSoft(1)构建嵌入式交叉编译环境
  4. poj 1985 Cow Marathon
  5. XPath具体解释
  6. Posix 共享内存区
  7. 深度解析javascript中的浅复制和深复制
  8. [笔记]我的Linux入门之路 - 03.Java环境搭建
  9. 微信小程序--录音
  10. [HAOI2018]奇怪的背包 (DP,数论)
  11. MySQL--使用innodb_force_recovery修复数据库异常
  12. python dataframe astype 字段类型转换
  13. PHP核心技术——接口
  14. php计算中英文混合或中文字符串的字数
  15. c#中获得MD5字符串方法
  16. 使用 mybatis + flying-0.9.4 的电商后端
  17. 求解范围中 gcd(a,b)== prime 的有序对数
  18. 【bzoj2789】[Poi2012]Letters 树状数组求逆序对
  19. 「LuoguP2252」 取石子游戏(威佐夫博弈
  20. mysql 用 group by 和 order by同时使用

热门文章

  1. [洛谷P1279][题解]字串距离
  2. [译]Vulkan教程(28)Image视图和采样器
  3. ETCD:gRPC命名与发现
  4. js|jq获取兄弟节点,父节点,子节点
  5. http请求post,文件导出兼容IE10+
  6. js的委托事件----Vue
  7. 假设高度已知,请写出三栏布局,其中左右各为300px 中间自适用
  8. js实现防抖函数和节流函数
  9. 【原创】REPORT自动生成工具
  10. 2018最新cocoapods详细安装和使用