uvalive 3276 The Great Wall Game
题意:
一个n * n的棋盘上放着n个棋子,现在要求把这n个棋子用最少的步数移到同一条直线上,即同一列同一行或者同一对角线(两条)。输出最少的步数(只能往四个方向移动,即正东,正西,正南,正北)。
思路:
每个棋子唯一对应一个格子,每个棋子不能在同一个格子,那么就相当于一个二分图(强行二分图)。
因为n很小,所以可以枚举每一行,每一列,两条对角线,然后每个点移动到每一条直线的每一个格子都有一个距离,那么这个点就向格子连一条权值为距离的边,这个问题就转化成了求所有最佳完美的匹配中的最小值,用KM算法。
因为我们求的是最小步数,所以求的是带权二分图的最小匹配。
求最小匹配,就将每一条边的权值取反,然后求最大匹配,再将最后的结果取反就得到了最小匹配的结果。
复杂度为O(n^4)。
注意:输出很坑,每一个答案后都有一个换行,并不是两个中间输出一个,也就是说,最后一个后面也有换行。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std; const int N = ;
const int inf = 0x3f3f3f3f; int love[N][N];
int lx[N],ly[N];
bool visx[N],visy[N];
int match[N];
int slack[N]; struct node
{
int x,y; node(int aa,int bb)
{
x = aa;
y = bb;
}
}; vector<node> vn; int mabs(int x)
{
return x >= ? x : -x;
} bool dfs(int u,int n)
{
visx[u] = ; for (int i = ;i <= n;i++)
{
if (visy[i]) continue; int gap = lx[u] + ly[i] - love[u][i]; if (gap == )
{
visy[i] = ; if (match[i] == - || dfs(match[i],n))
{
match[i] = u;
return true;
}
}
else
{
slack[i] = min(gap,slack[i]);
}
} return false;
} int km(int n)
{
memset(match,-,sizeof(match));
memset(ly,,sizeof(ly)); for (int i = ;i <= n;i++)
{
lx[i] = love[i][]; for (int j = ;j <= n;j++)
{
lx[i] = max(lx[i],love[i][j]);
}
} for (int i = ;i <= n;i++)
{
memset(slack,inf,sizeof(slack)); while ()
{
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy)); if (dfs(i,n)) break; int d = inf; for (int j = ;j <= n;j++)
{
if (!visy[j]) d = min(d,slack[j]);
} for (int j = ;j <= n;j++)
{
if (visx[j]) lx[j] -= d; if (visy[j]) ly[j] += d;
}
} } int res = ; for (int i = ;i <= n;i++)
{
res += love[match[i]][i];
} return res;
} int main()
{
int n;
int kase = ; while (scanf("%d",&n) != EOF && n)
{
vn.clear(); for (int i = ;i < n;i++)
{
int a,b; scanf("%d%d",&a,&b); vn.push_back(node(a,b));
} //if (kase) printf("\n"); int ans = 1e8; for (int i = ;i <= n;i++)
{
for (int j = ;j < vn.size();j++)
{
for (int k = ;k <= n;k++)
{
int dx = mabs(vn[j].x - i);
int dy = mabs(vn[j].y - k);
love[j+][k] = -(dx + dy);
}
} int tmp = -km(n); //printf("%d **\n",tmp); ans = min(tmp,ans);
} for (int i = ;i <= n;i++)
{
for (int j = ;j < vn.size();j++)
{
for (int k = ;k <= n;k++)
{
int dy = mabs(vn[j].y - i);
int dx = mabs(vn[j].x - k);
love[j+][k] = -(dx + dy);
}
} int tmp = -km(n); ans = min(tmp,ans); //printf("%d **\n",tmp);
} for (int i = ;i <= n;i++)
{
for (int j = ;j < vn.size();j++)
{
int dx = mabs(vn[j].x - i);
int dy = mabs(vn[j].y - i); love[j+][i] = -(dx + dy);
}
} ans = min(ans,-km(n)); for (int i = ;i <= n;i++)
{
for (int j = ;j < vn.size();j++)
{
int dx = mabs(vn[j].x - i);
int dy = mabs(vn[j].y - (n - i + )); love[j+][i] = -(dx + dy);
}
} ans = min(ans,-km(n)); printf("Board %d: %d moves required.\n\n",++kase,ans);
} return ;
}
uvalive 3276 The Great Wall Game的更多相关文章
- UVALive 5097 Cross the Wall
贪心思想,$dp$,斜率优化. 首先将人按照$w$从大到小排序,如果$w$一样,按$h$从大到小排.这样一来,某位置之后,比该位置$h$小的都是不需要考虑的. 因此,形成了如下图所示的结果: 即第一个 ...
- [kuangbin带你飞]专题二十 斜率DP
ID Origin Title 20 / 60 Problem A HDU 3507 Print Article 13 / 19 Problem B HDU 2829 Lawr ...
- KUANGBIN带你飞
KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题 //201 ...
- 【转】斜率优化DP和四边形不等式优化DP整理
(自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...
- [kuangbin带你飞]专题1-23题目清单总结
[kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...
- ACM--[kuangbin带你飞]--专题1-23
专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 FliptilePOJ 1426 Find T ...
- UVALive 4425 Another Brick in the Wall 暴力
C - Another Brick in the Wall Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & ...
- UVALive 2453 Wall (凸包)
题意:给你一个多边形的城堡(多个点),使用最短周长的城墙将这个城堡围起来并保证城墙的每个点到城堡上的每个点的距离都不小于l 题解:因为两点间的直线一定比折线短,所以这样做 先使用所有点求得一个凸包,接 ...
- UVALive 5066 Fire Drill BFS+背包
H - Fire Drill Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Sta ...
随机推荐
- Python文件操作---正斜杠与反斜杠
Python中的正斜杠与反斜杠 首先,"/"左倾斜是正斜杠,"\"右倾斜是反斜杠,可以记为:除号是正斜杠一般来说对于目录分隔符,Unix和Web用正斜杠/,Wi ...
- python server
#!/usr/bin/env python #coding=utf-8 # modifyDate: 20120808 ~ 20120810 # 原作者为:bones7456, http://li2z. ...
- webpack中loader和plugin的概念理解
对于 loader ,它就是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将 A.scss 或 A.less 转变成 B.css,单纯的文件转换过程: 对于 plugin,它就是一个扩 ...
- (4.22)Microsoft 管理控制台启用 SSL 加密的 SQL Server 实例
如何通过使用 Microsoft 管理控制台启用 SSL 加密的 SQL Server 实例 关键词:MSSQL加密,sql server加密,sql server客户端与服务器传输内容加密 转自:h ...
- vue 上传图片 input=file
一.逻辑 点击li触发事件chooseImage 即触发input标签事件photoChange input标签事件photoChange file返回的是如下变量 模拟上传表单方法 执行上传 二.代 ...
- koa : Express出品的下一代基于Node.js的web框架
https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434501579966a ...
- Openvpn配置文件详解
一.vars配置文件 vars配置文件的主要内容如下: cat vars |grep -vE "^#|^$" KEY_DIR定义key生成的目录. KEY_SIZE定义生成私钥的大 ...
- 利用 PorterDuff 动态改变资源色值,缩减安装包大小
利用 PorterDuff 改变资源原有色值,从而实现只需要一个资源文件,就可以表示几种不同的状态,如在线或者离线等等 public Drawable colorDrawable(Resources ...
- Linux下搭建redis服务器
1.redis需要gcc的编译环境,在线安装gcc:# yum install gcc-c++ 2.上传redis的压缩包到Linux系统,解压 3.进入源码目录,编译(注意要有makefile), ...
- 【Linux】-NO.8.Linux.4.Command.1.001-【Common Command】-
1.0.0 Summary Tittle:[Linux]-NO.8.Linux.4.Command.1.001-[Common Command]- Style:Linux Series:Command ...