[SDOI2012]象棋
题解:
sd的题目也真是奇怪
第一题有了最短路第二题还有
第二题有了网络流第三题还有
显然是可以网络流的
但考虑每个点只能存在一个这个条件
刚开始我以为是建分层图。。但发现这个时间复杂度太高了
其实我们考虑当两个人到一个点的时候可以交换速度(常用思想)
所以如果有解那么这个条件就是没有用的
所以也就是说这个条件是没有用的
那就变成了二分图最大权匹配
代码:
#include <bits/stdc++.h>
#define N 40000
#define maxn 500000
using namespace std;
struct re{
int a,b,c,from,flow,cost;
}a[maxn];
struct ree{
int a,b,c;
}e[maxn];
int l2,l,head[N],head2[N];
void arr(int x,int y,int z,int flow,int cost)
{
a[++l].a=head[x];
a[l].b=y;
a[l].c=z;
a[l].flow=flow;
a[l].cost=cost;
a[l].from=x;
head[x]=l;
}
#define INF 1e9
int sum,d[N],s,t,p[N],aa[N],n,m;
bool inq[N];
bool bellmanford(int &flow,int &cost)
{
for (int i=;i<=sum;i++) d[i]=INF;
memset(inq,,sizeof(inq));
d[s]=; inq[s]=; aa[s]=INF;
queue<int>q;
q.push(s);
while (!q.empty())
{
int x=q.front(); q.pop();
int u=head[x];
while (u)
{
int v=a[u].b;
if (a[u].c>a[u].flow&&d[v]>d[x]+a[u].cost)
{
d[v]=d[x]+a[u].cost;
p[v]=u;
aa[v]=min(aa[x],a[u].c-a[u].flow);
if (!inq[v])
{
q.push(v); inq[v]=;
}
}
u=a[u].a;
}
inq[x]=;
}
if (d[t]==INF) return();
flow+=aa[t];
cost+=d[t]*aa[t];
int x=t;
while (x!=s)
{
int u=p[x];
a[u].flow+=aa[t];
if (u%) a[u+].flow-=aa[t]; else a[u-].flow-=aa[t];
x=a[u].from;
}
return ;
}
int flow,cost;
void mincost()
{
while (bellmanford(flow,cost));
}
int dx[]={,,,-,-};
int dy[]={,,-,,-};
queue<int> q;
bool ff[][];
char cc[N];
int js(int x,int y)
{
return((x-)*m+y);
}
bool pd(int x,int y)
{
if (x>=&&x<=n&&y>=&&y<=m&&!ff[x][y]) return();
else return();
}
void arr2(int x,int y)
{
e[++l2].a=head2[x];
e[l2].b=y;
head2[x]=l2;
}
int k,a1,b1;
int x1[N],x2[N],y3[N],y4[N],dis[N];
bool vis[N];
int main()
{
freopen("noi.in","r",stdin);
freopen("noi.out","w",stdout);
std::ios::sync_with_stdio(false);
cin>>n>>m>>k>>a1>>b1;
for (int i=;i<=n;i++)
{
cin>>cc;
int len=strlen(cc);
for (int j=;j<len;j++)
if (cc[j]=='*') ff[i][j+]=;
}
for (int i=;i<=k;i++)
cin>>x1[i]>>y3[i];
for (int i=;i<=k;i++)
cin>>x2[i]>>y4[i];
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (pd(i,j))
{
for (int i1=;i1<=;i1++)
{
if (pd(i+dx[i1]*a1,j+dy[i1]*b1))
{
int k1=js(i,j);
int k2=js(i+dx[i1]*a1,j+dy[i1]*b1);
arr2(k1,k2);
}
if (pd(i+dx[i1]*b1,j+dy[i1]*a1))
{
int k1=js(i,j);
int k2=js(i+dx[i1]*b1,j+dy[i1]*a1);
arr2(k1,k2);
}
}
}
sum=*k+;
for (int i=;i<=k;i++)
{
int ax1=js(x1[i],y3[i]);
for (int j=;j<=n*m;j++)
dis[j]=INF;
memset(vis,,sizeof(vis));
dis[ax1]=; q.push(ax1); vis[ax1]=;
while (!q.empty())
{
int x2=q.front(); q.pop();
int u=head2[x2];
while (u)
{
int v=e[u].b;
if (!vis[v])
{ dis[v]=dis[x2]+;
q.push(v);
vis[v]=;
}
u=e[u].a;
}
}
for (int j=;j<=k;j++)
{
int ax2=js(x2[j],y4[j]);
arr(i,j+k,,,dis[ax2]);
arr(j+k,i,,,-dis[ax2]);
}
}
s=; t=*k+;
for (int i=;i<=k;i++)
{
arr(s,i,,,); arr(i,s,,,);
arr(i+k,t,,,); arr(t,i+k,,,);
}
mincost();
cout<<cost;
return ;
}
[SDOI2012]象棋的更多相关文章
- 题解 Luogu P2499: [SDOI2012]象棋
关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可 ...
- SDOI2012 Round1 day2 象棋(chess)解题报告
本题的难点是“移动过程中不能出现多颗棋子同时在某一格的情况”. 事实上,可以忽略此条件,因为棋子是相同的,我们可以用合法的等效方案替代一棋子越过另一棋子的情况:A.B.C三格,A能在一步走到B,B也能 ...
- HTML5学习总结——canvas绘制象棋(canvas绘图)
一.HTML5学习总结——canvas绘制象棋 1.第一次:canvas绘制象棋(笨方法)示例代码: <!DOCTYPE html> <html> <head> & ...
- 局域网象棋游戏(C++实现,使用Socket,界面使用Win32,CodeBlocks+GCC编译)
目录 成果 运行效果图 过程 1. 首先的问题是下棋的两端应该是什么样的? 2. 接下来的问题是怎么表示,怎么存储? 3. 然后应该怎么通信呢? 代码 main.cpp chinese_chess.h ...
- BZOJ 2705: [SDOI2012]Longge的问题 [欧拉函数]
2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 2553 Solved: 1565[Submit][ ...
- 简单的c#winform象棋游戏(附带源码)
算法源自网络(网络源码连接:http://www.mycodes.net/161/6659.htm) 整体思路:用二维数组构建棋盘每一个数组元素封装为一个picturebox附带若干属性(例如:棋 ...
- BZOJ 1801中国象棋 DP
1801: [Ahoi2009]chess 中国象棋 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1426 Solved: 826[Submit][ ...
- BZOJ 2705: [SDOI2012]Longge的问题
2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 2554 Solved: 1566[Submit][ ...
- C#中国象棋+游戏大厅 服务器 + 客户端源码
来源:www.ajerp.com/bbs C#中国象棋+游戏大厅 服务器 + 客户端源码 源码开源 C#版中国象棋(附游戏大厅) 基于前人大虾的修改版 主要用委托实现 服务器支持在线人数,大厅桌数的设 ...
随机推荐
- 〖C语言学习笔记 〗(二) 数据类型
前言 本文为c语言的学习笔记,很多只是留下来占位的 数据类型 助记:变量就是在内存中挖个坑并给这个坑命名,而数据类型就是挖内存的坑的尺寸 基础类型 整数类型: short int int long i ...
- Linux TCP 连接数
查看 TCP 连接数 : 每一个 IP 访问的链接数:head 默认 前10 netstat -na|grep ESTABLISHED|awk '{print $5}'|awk -F: '{print ...
- JS 中对变量类型判断的几种方式
文章整理搬运,出处不详,如有侵犯,请联系~ 数据类型判断和数据类型转换代码工具 在 JS 中,有 5 种基本数据类型和 1 种复杂数据类型,基本数据类型有:Undefined, Null, Boo ...
- php 无法正确获取系统当前时间的解决办法
今天捣鼓一个统计系统时让用户自动录入用户信息,后台使用PHP的date()函数来获取系统时间,发现时间跟当前时间对不上,后来是因为PHP默认的时区是UTC,应该将其时区设置为北京时间. 方法一:修改p ...
- 解决ipad连接不上电脑的问题
检查一下信息: 1.iTunes是否安装 2.数据线是否完好 3.检查下图中的两个设备是否开启 4.最后一步是最恶心的:是否关闭了防火墙!!!! 操作步骤如下图示 我就是因为打开了防火墙,所以一直连接 ...
- nvm安装与使用
1.nvm是什么 nvm全名node.js version management,顾名思义是一个nodejs的版本管理工具.通过它可以安装和切换不同版本的nodejs.下面列出下载.安装及使用方法. ...
- 【转】Python之函数进阶
[转]Python之函数进阶 本节内容 上一篇中介绍了Python中函数的定义.函数的调用.函数的参数以及变量的作用域等内容,现在来说下函数的一些高级特性: 递归函数 嵌套函数与闭包 匿名函数 高阶函 ...
- 字符驱动之二操作方法(struct file_operations)【转】
转自:http://blog.chinaunix.net/uid-26837113-id-3157515.html 从上一篇我们看到了字符驱动的三个重要结构,那我现在跟大家详细的说说 struct f ...
- find结合rm删除或mv移动文件的方法
删除过期的备份文件,多用find结合rm方法,可以使用-exec或xargs -exec rm -rf {} \; 或 find /home/mysqlbackup -name "*$thi ...
- centos6.5下编译安装mariadb-10.0.20
源码编译安装mariadb-10.0.20.tar.gz 一.安装cmake编译工具 跨平台编译器 # yum install -y gcc* # yum install -y cmake 解决依赖关 ...