SDOI2012 Round1 day2 象棋(chess)解题报告
本题的难点是“移动过程中不能出现多颗棋子同时在某一格的情况”。
事实上,可以忽略此条件,因为棋子是相同的,我们可以用合法的等效方案替代一棋子越过另一棋子的情况:A、B、C三格,A能在一步走到B,B也能在一步走到C。
在A的棋子需要走到存在棋子的B,接着走到C。此情形我们可以看成在B的棋子先走到C,接着在A的棋子走到B。
BFS预处理出每个初始位置走到每个终止位置的最少步数。
把初始位置抽象成二部图的左部,终止位置抽象成二部图的右部,左右之间边权为最少步数。
那么次二部图的完备匹配对应着一种方案,匹配的边权和对应最少总步数。
可用最佳匹配解决。
期望得分:
70(裸费用流)
90(n^4的KM算法)
100(n^3的KM算法)
//跑费用流,极限90(不会KM~~)
//by shenben
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
#define setfire(name) freopen(#name".in","r",stdin);freopen(#name".out","w",stdout);
using namespace std;
const int N=;
const int Z=;
const int inf=0x3f3f3f3f;
char mp[N][N];bool vis[N][N];int id[N][N];
int n,m,k,S,T,a,b,ans,f[Z][];
int dx[],dy[];
struct M{
int x,y,step;
M(int x=,int y=,int step=):x(x),y(y),step(step){}
};
struct edge{int v,next,cap,cost;}e[Z*Z*];int tot=,head[Z<<];bool mark[Z<<];
int dist[Z][Z],prev[Z<<],dis[Z<<],q[Z*];
inline int read(){
register int x=;register char ch=getchar();
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x;
}
inline void add(int x,int y,int z,int cost){
e[++tot].v=y;e[tot].cap=z;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].cap=;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot;
}
inline void init(){
n=read();m=read();k=read();a=read();b=read();
if(n==&&m==&&k==&&a==&&b==){puts("");exit();}
dx[]=a;dx[]=a;dx[]=-a;dx[]=-a;dx[]=b;dx[]=b;dx[]=-b;dx[]=-b;
dy[]=b;dy[]=-b;dy[]=b;dy[]=-b;dy[]=-a;dy[]=a;dy[]=a;dy[]=-a;
for(int i=;i<=n;i++) scanf("%s",mp[i]+);
for(int i=;i<=k;i++) f[i][]=read(),f[i][]=read();
for(int i=,x,y;i<=k;i++) x=read(),y=read(),id[x][y]=i;
}
inline bool inside(int x,int y){
return (x>&&x<=n&&y>&&y<=m);
}
inline void bfs(int num){
int cnt=,sx=f[num][],sy=f[num][];
memset(vis,,sizeof vis);
queue<M>q;q.push(M(sx,sy,));
if(id[sx][sy]){
dist[num][id[sx][sy]]=;
if(++cnt==k) return ;
}
while(q.size()){
M now=q.front();q.pop();
for(int i=,nx,ny;i<=;i++){
nx=now.x+dx[i];ny=now.y+dy[i];
if(vis[nx][ny]||!inside(nx,ny)||mp[nx][ny]=='*') continue;
vis[nx][ny]=;
if(id[nx][ny]){
if(dist[num][id[nx][ny]]==inf) dist[num][id[nx][ny]]=now.step+;
if(++cnt==k) return ;
}
q.push(M(nx,ny,now.step+));
}
}
}
inline void mapping(){
memset(dist,inf,sizeof dist);
S=;T=k<<|;
for(int i=;i<=k;i++){
bfs(i);
}
for(int i=;i<=k;i++){
for(int j=;j<=k;j++){
if(dist[i][j]!=inf) add(i,j+k,,dist[i][j]);
}
}
for(int i=;i<=k;i++) add(S,i,,),add(i+k,T,,);
}
/*稠密图EK不如zkw跑的快
inline bool spfa(){
for(int i=S;i<=T;i++) mark[i]=0,dis[i]=inf;
unsigned short h=0,t=1;q[t]=S;dis[S]=0;
while(h!=t){
int x=q[++h];mark[x]=0;
for(int i=head[x];i;i=e[i].next){
if(e[i].cap&&dis[e[i].v]>dis[x]+e[i].cost){
dis[e[i].v]=dis[x]+e[i].cost;
prev[e[i].v]=i;
if(!mark[e[i].v]){
mark[e[i].v]=1;
if(dis[e[i].v]<dis[x]) q[h--]=e[i].v;
else q[++t]=e[i].v;
}
}
}
}
return dis[T]!=inf;
}
inline void augment(){
int flow=inf;
for(int i=T;i!=S;i=e[prev[i]^1].v){
flow=min(flow,e[prev[i]].cap);
}
for(int i=T;i!=S;i=e[prev[i]^1].v){
e[prev[i]].cap-=flow;
e[prev[i]^1].cap+=flow;
}
ans+=flow*dis[T];
}*/
inline bool spfa(){
for(int i=S;i<=T;i++) mark[i]=,dis[i]=inf;
int h=,t=;q[t]=T;dis[T]=;mark[T]=;
while(h!=t){
int x=q[++h];mark[x]=;
for(int i=head[x];i;i=e[i].next){
int v=e[i].v;
if(e[i^].cap&&dis[v]>dis[x]+e[i^].cost){
dis[v]=dis[x]+e[i^].cost;
if(!mark[v]){
mark[v]=;
q[++t]=v;
}
}
}
}
return dis[S]<inf;
}
int dfs(int x,int f){
mark[x]=;
if(x==T) return f;
int used=,w;
for(int i=head[x];i;i=e[i].next){
int v=e[i].v;
if(!mark[v]&&e[i].cap&&dis[v]+e[i].cost==dis[x]){
w=dfs(v,min(f-used,e[i].cap));
e[i].cap-=w;e[i^].cap+=w;
ans+=w*e[i].cost;
used+=w;
if(used==f) return used;
}
}
return used;
}
inline void zkw(){
while(spfa()){
mark[T]=;
while(mark[T]){
memset(mark,,sizeof mark);
dfs(S,inf);
}
}
}
int main(){
setfire(chess);
init();
mapping();
zkw();
//while(spfa()) augment();
printf("%d",ans);
return ;
}
//最后一个点5.39s,zkw费用流死活跑不过去
SDOI2012 Round1 day2 象棋(chess)解题报告的更多相关文章
- SDOI2012 Round1 day2 拯救小云公主(dis)解题报告
#include<cstdio> #include<cmath> #include<iostream> using namespace std; typedef l ...
- SDOI2012 Round1 day2 集合(set)解题报告
//=====================以上为官方题解==============// 数据略水,暴力枚举50. 把边按照升序排一遍,在询问,水过. #include<cstdio> ...
- 洛谷 P4363 [九省联考2018]一双木棋chess 解题报告
P4363 [九省联考2018]一双木棋chess 题目描述 菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落 ...
- 洛谷 P2498 [SDOI2012]拯救小云公主 解题报告
P2498 [SDOI2012]拯救小云公主 题目描述 英雄又即将踏上拯救公主的道路-- 这次的拯救目标是--爱和正义的小云公主. 英雄来到\(boss\)的洞穴门口,他一下子就懵了,因为面前不只是一 ...
- 雅礼集训 Day2 T3 联盟 解题报告
联盟 题目描述 \(\text{G}\) 国周边的 \(n\) 个小国家构成一个联盟以抵御 \(\text{G}\) 国入侵, 为互相支援,他们建立了\(n−1\) 条双向通路, 使得任意两个国家可以 ...
- noip2013 Day2 T2 花匠 解题报告
题目: 3289 花匠 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大, ...
- 【百度之星2014~初赛(第二轮)解题报告】Chess
声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载.可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...
- GX/GZOI2019 day2 解题报告
GX/GZOI2019 day2 解题报告 题目链接 逼死强迫症 旅行者 旧词 t1 逼死强迫症 显然地,记 \(f(i)\) 为长度为 \(i\) 的木板的答案,可得: \(\\\) \[f(i)= ...
- 【NOIP2015】提高day2解题报告
题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...
随机推荐
- django book用户认证学习
用户与Authentication 通过session,我们可以在多次浏览器请求中保持数据, 接下来的部分就是用session来处理用户登录了. 当然,不能仅凭用户的一面之词,我们就相信,所以我们需要 ...
- log4j教程 12、日志记录到数据库
log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 buff ...
- ES集群爆红,有未分配的片
curl GET http://192.168.46.166:9200/_cluster/health?level=indices curl -XPUT '192.168.46.166:9200/_c ...
- netty handle处理流程
server handlerAdded server channelRegistered server channelActive server read server channelInactive ...
- 2017.5.16 comparator和comparable的比较及使用
参考来自: http://blog.csdn.net/lifuxiangcaohui/article/details/41543347 http://www.cnblogs.com/liuyuanyu ...
- 关于Laravel5.2在php5.3.6X和在php7.1.10下的内存溢出
php5.3.6X是编译安装,在debug模式下,频繁报出内存泄露警告 php7.1.10下则不会有此错误. 顺便提下:测试发现ThinkPHP也不会有该内存泄露警告! 希望知道如何解决该问题的童鞋能 ...
- highCharts怎样实现json数组数据的图形展示
昨天花了一天的时间学习了一下highcharts.主要的内容差点儿相同都看了一遍,然后试着写了一个完整的demo,期间可谓百转千回.费了不少功夫.终于还是实现了我所想要的效果图,接下来我将怎样实现统计 ...
- 基于RxJava2+Retrofit2精心打造的Android基础框架
代码地址如下:http://www.demodashi.com/demo/12132.html XSnow 基于RxJava2+Retrofit2精心打造的Android基础框架,包含网络.上传.下载 ...
- java代理ip有效检测
java实现代理ip有效检测,依赖Apache的HttpClient 正式版: /** * 批量代理IP有效检测 * * @param pro ...
- iOS时间间隔判断
如何计算两个NSDate之间的时间间隔呢? timeIntervalSinceDate: Returns the interval between the receiver and another g ...