最短路

吐槽一下。。。最先开始写了个地图哈希,6kb,然后不是正解,又写了个spfa,4kb,还是不对,无奈抄标程,结果把spfa改成dijiestra就对了。。。

由于只有两个变量,所以我们设一个四维状态,d[x0][y0][x1][y1],然后就可以跑最短路了。如果是多维的话就得用哈希了。

但是那个终点的位置不固定,而且得做两次,因为控制的价钱不一样,所以两次取最小值。

#include<bits/stdc++.h>
using namespace std;
const int dx[] = {, , -, }, dy[] = {-, , , };
struct position {
int x0, y0, x1, y1;
position(int x0 = , int y0 = , int x1 = , int y1 = ) : x0(x0), y0(y0), x1(x1), y1(y1) {}
bool friend operator < (position A, position B)
{
return A.x0 < B.x0;
}
};
int T, sx0, sy0, sx1, sy1;
queue<position> q;
set<position> inq;
int d[][][][];
char Map[][];
void spfa()
{
memset(d, 0x3f3f, sizeof(d));
q.push(position(sx0, sy0, sx1, sy1));
d[sx0][sy0][sx1][sy1] = ;
while(!q.empty())
{
position x = q.front();
q.pop();
inq.erase(x);
// if(x.x0 < 1 || x.x1 < 1 || x.y0 < 1 || x.y1 < 1 || x.x0 > 10 || x.x1 > 10 || x.y0 > 15 || x.y1 > 15 || (Map[x.x0][x.y0] == 'O' && Map[x.x1][x.y1] == 'O')) continue;
if(Map[x.x0][x.y0] == 'O' && Map[x.x1][x.y1] == 'O') continue;
for(int i = ; i < ; ++i)
{
position t = x;
int cost = d[t.x0][t.y0][t.x1][t.y1];
if(Map[t.x0][t.y0] != 'O')
{
t.x0 += dx[i];
t.y0 += dy[i];
cost += ;
if(Map[t.x0][t.y0] == 'X')
{
t.x0 = x.x0;
t.y0 = x.y0;
}
}
if(Map[t.x1][t.y1] != 'O')
{
t.x1 += dx[i];
t.y1 -= dy[i];
cost += ;
if(Map[t.x1][t.y1] == 'X')
{
t.x1 = x.x1;
t.y1 = x.y1;
}
}
if(d[t.x0][t.y0][t.x1][t.y1] > cost)
{
d[t.x0][t.y0][t.x1][t.y1] = cost;
if(inq.find(position(t.x0, t.y0, t.x1, t.y1)) == inq.end())
{
inq.insert(position(t.x0, t.y0, t.x1, t.y1));
q.push(position(t.x0, t.y0, t.x1, t.y1));
}
}
}
position t = x;
int cost = d[t.x0][t.y0][t.x1][t.y1];
if(abs(x.x0 - x.x1) + abs(x.y0 - x.y1) == && ((Map[x.x0][x.y0] == 'O') ^ (Map[x.x1][x.y1] == 'O')))
{
if(Map[x.x0][x.y0] == 'O')
{
t.x0 = x.x1;
t.y0 = x.y1;
}
else
{
t.x1 = x.x0;
t.y1 = x.y0;
}
cost += ;
}
if(d[t.x0][t.y0][t.x1][t.y1] > cost)
{
d[t.x0][t.y0][t.x1][t.y1] = cost;
if(inq.find(position(t.x0, t.y0, t.x1, t.y1)) == inq.end())
{
inq.insert(position(t.x0, t.y0, t.x1, t.y1));
q.push(position(t.x0, t.y0, t.x1, t.y1));
}
}
}
printf("%d\n", d[][][][] == ? - : d[][][][]);
}
int main()
{
scanf("%d", &T);
while(T--)
{
inq.clear();
for(int i = ; i <= ; ++i)
for(int j = ; j <= ; ++j)
Map[i][j] = 'X';
for(int i = ; i <= ; ++i)
{
char s[];
scanf("%s", s + );
for(int j = ; j <= ; ++j)
{
if(s[j] == 'H') s[j] = '.';
Map[i][j] = s[j];
}
}
scanf("%d%d%d%d", &sx0, &sy0, &sx1, &sy1);
spfa();
}
return ;
}

zoj3478的更多相关文章

随机推荐

  1. Java 基础入门随笔(2) JavaSE版——关键字、进制转换、类型转换

    1.Java语言-关键字 关键字:被java语言赋予了特殊含义的词,特点是所有的字母都为小写. java涉及到的关键字整理: 用于定义数据类型的关键字 class interface byte sho ...

  2. ajax不执行success的问题

    有时候经常会遇到ajax请求后台,然后后台返回数据后,不触发ajax的success函数的问题,归根到底,这与ajax的参数设置dataType和后台的返回值的类型有关,现总结如下: 一.后台返回值的 ...

  3. 计组_IEEE754_练习题

    IEEE754   阶码:移码:尾数:原码 一个规格化的32位浮点数x的真值可表示为:          x=(-1)^s×(1. M) × 2^(E-127)       e=E-127 其中尾数域 ...

  4. .mm c++ oc 混编

    When you create a static library you don't link in the dependent libraries. As a result, when you re ...

  5. unittest 是什么?怎么用?

    unittest单元测试框架详解 https://www.cnblogs.com/fighter007/p/8245063.html unittest最详细的解说 https://www.cnblog ...

  6. Unity中确定时间是否在一定范围内

    NowTime = DateTime.Now.ToLocalTime(); Timeyear = DateTime.Now.ToLocalTime().ToString("yyyy-MM-d ...

  7. 50.percentiles百分比算法以及网站延时统计

    主要知识点 percentiles的用法     现有一个需求:比如有一个网站,记录下了每次请求的访问的耗时,需要统计tp50,tp90,tp99 tp50:50%的请求的耗时最长在多长时间 tp90 ...

  8. 【codeforces 757D】Felicity's Big Secret Revealed

    [题目链接]:http://codeforces.com/problemset/problem/757/D [题意] 给你一个01串; 让你分割这个01串; 要求2切..n+1切; 对于每一种切法 所 ...

  9. java中redis的分布式锁工具类

    使用方式 try { if(PublicLock.getLock(lockKey)){ //这里写代码逻辑,执行完后需要释放锁 PublicLock.freeLock(lockKey); } } ca ...

  10. bx值

    bx值 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem De ...