费用流

这种棋盘模型大概都是网络流吧

首先我们知道棋子之间不会影响到达目标的步数,那么就好做了,枚举终点,然后就是最小权匹配了,因为就是寻找总和最小,然后费用流就行了。

#include<bits/stdc++.h>
using namespace std;
const int N = , inf = 0x3f3f3f3f;
struct data {
int x, y;
} a[N];
struct edge {
int nxt, to, f, c;
} e[N * N];
int n, S, T, tot, cnt = , ans, kase;
int head[N], dis[N], q[N], Map[N][N], pree[N], prevv[N], inq[N];
void link(int u, int v, int f, int c)
{
e[++cnt].nxt = head[u];
head[u] = cnt;
e[cnt].to = v;
e[cnt].f = f;
e[cnt].c = c;
}
void insert(int u, int v, int f, int c)
{
link(u, v, f, c);
link(v, u, , -c);
}
bool spfa()
{
int l = , r = ;
memset(dis, 0x3f3f, sizeof(dis));
dis[] = ;
q[++r] = ;
while(l <= r)
{
int u = q[l++];
inq[u] = ;
for(int i = head[u]; i; i = e[i].nxt) if(e[i].f && dis[e[i].to] > dis[u] + e[i].c)
{
pree[e[i].to] = i;
prevv[e[i].to] = u;
dis[e[i].to] = dis[u] + e[i].c;
if(!inq[e[i].to])
{
inq[e[i].to] = ;
q[++r] = e[i].to;
}
}
}
return dis[T] != 0x3f3f3f3f;
}
int getflow()
{
int now = T, delta = inf;
while(now)
{
delta = min(delta, e[pree[now]].f);
now = prevv[now];
}
now = T;
while(now)
{
e[pree[now]].f -= delta;
e[pree[now] ^ ].f += delta;
now = prevv[now];
}
return delta * dis[T];
}
int maxcostflow()
{
int ret = ;
while(spfa()) ret += getflow();
return ret;
}
void build()
{
memset(head, , sizeof(head));
cnt = ;
for(int i = ; i <= n; ++i) insert(S, i, , );
for(int i = ; i <= n; ++i)
for(int x = ; x <= n; ++x)
for(int y = ; y <= n; ++y) if(Map[x][y])
insert(i, Map[x][y], , abs(a[i].x - x) + abs(a[i].y - y));
for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j) if(Map[i][j])
insert(Map[i][j], T, , );
}
int main()
{
while(scanf("%d", &n))
{
if(!n) break;
T = * n + ;
ans = inf;
for(int i = ; i <= n; ++i) scanf("%d%d", &a[i].x, &a[i].y);
for(int i = ; i <= n; ++i)
{
memset(Map, , sizeof(Map));
tot = n;
for(int j = ; j <= n; ++j) Map[i][j] = ++tot;
build();
ans = min(ans, maxcostflow());
memset(Map, , sizeof(Map));
tot = n;
for(int j = ; j <= n; ++j) Map[j][i] = ++tot;
build();
ans = min(ans, maxcostflow());
}
memset(Map, , sizeof(Map));
tot = n;
for(int i = ; i <= n; ++i) Map[i][i] = ++tot;
build();
ans = min(ans, maxcostflow());
memset(Map, , sizeof(Map));
tot = n;
for(int i = ; i <= n; ++i) Map[i][n - i + ] = ++tot;
build();
ans = min(ans, maxcostflow());
printf("Board %d: %d moves required.\n\n", ++kase, ans);
}
return ;
}

LA3276的更多相关文章

随机推荐

  1. Python开发工具搭建-Pycharm

    PyCharm2017. 3.X专业版 安装使用. 注册码激活 本文以 Windows系统 为例: 1.开发工具获取及下载 Anaconda(Python 的集成工具 ) 下载地址: https:// ...

  2. Centos6.7 编译安装 Apache PHP

    Centos6.7 编译安装 Apache PHP 原文地址:http://www.cnblogs.com/caoguo/p/4968039.html ##### Apache 编译安装 #### [ ...

  3. Build Tool-自动化构建工具

    输入:工程文件+编译说明文件: 处理:自动化构建工具+编译器: 输出:可执行文件. 相对于手动编译. Historically, build automation was accomplished t ...

  4. mybatis 简单的入门实例

    第一步:添加mybaties的架包 第二步:配置mybaties的文件 <?xml version="1.0" encoding="UTF-8" ?> ...

  5. SpringMVC与MyBatis整合方法

    一.springmvc+mybaits的系统架构: 第一步:整合dao层 mybatis和spring整合,通过spring管理mapper接口. 使用mapper的扫描器自动扫描mapper接口在s ...

  6. CVPR 2017 Paper list

    CVPR2017 paper list Machine Learning 1 Spotlight 1-1A Exclusivity-Consistency Regularized Multi-View ...

  7. js中数组,字符串,对象常用方法总结

    时间对象方法 获取当前时间的毫秒数 1.var timestamp = Date.parse(new Date()); 2.var timestamp = (new Date()).valueOf() ...

  8. Luogu P1256 显示图像

    P1256 显示图像 题目描述 古老的显示屏是由N×M个像素(Pixel)点组成的.一个像素点的位置是根据所在行数和列数决定的.例如P(2,1)表示第2行第1列的像素点.那时候,屏幕只能显示黑与白两种 ...

  9. Python基础-画菱形

    方法一 n = int(input('请输入:')) for i in range(1, n, 2): print(('*'*i).center(n)) for i in reversed(range ...

  10. 【Codeforces 4D】Mysterious Present

    [链接] 我是链接,点我呀:) [题意] 要求长度和宽度都严格递增(选择一个序列) 然后你一开始有一个长度和宽度 要求这个一开始所给的长度和宽度能接在你选择的一段连续的长度宽度的开头 (且保持原来的性 ...