您的位置:首页 > 其它

poj 3878 zoj 3391 haunted graveyard

2011-04-29 19:14 337 查看
最短路 SPFA,题目没说清楚如果到达洞的出口又是洞的出口怎么解决,也没清楚 time indefinitely 是什么意思,而且如果洞的出口和洞的入口在同一个格子,如果时间是负的可以算 Never,可是如果是正的又该怎么算?,这样永远走不出去也走不回去,这又算 Never 还是 Impossible?总之建好了图 SPFA 硬上就 AC 了。

地图里每个非洞入口且非地图出口的格子和它周围至多四个格子(除石头)连一条边,边权 1。洞的入口格子只能与他的出口格子连一条边,边权是题目给的时间差。

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int INF = 0x3fffffff;
// Single Source Shortest Path
struct SSSP {
struct Edge {
int to, weight;
Edge(int t, int w): to(t), weight(w) {}
};

vector <vector <Edge> > adj;
vector <int> d;

void Init(int nodes) {
adj.clear();
adj.resize(nodes);
d.resize(nodes);
}

void NewEdge(int from, int to, int weight) {
adj[from].push_back(Edge(to, weight));
}

int SPFA(int source, int dest);
};
int SSSP::SPFA(int source, int dest) {
vector <int> cnt(adj.size(), 0);
queue <int> q;
vector <bool> inQ(adj.size(), false);

// init for spfa
fill(d.begin(), d.end(), INF);
d[source] = 0;
q.push(source);
inQ[source] = true;
while(! q.empty()) {
int n = q.front();
q.pop();
inQ
= false;
for(size_t i=0; i<adj
.size(); ++i) {
int a = adj
[i].to;
int w = adj
[i].weight;
if(d[a] > d
+ w) {
if(a == source) {
return -INF;
}
d[a] = d
+ w;
++cnt[a];
if(! inQ[a] && cnt[a] < adj.size()) {
q.push(a);
inQ[a] = true;
}
if(cnt[a] >= adj.size()) {
return -INF;
}
}
}
}
return d[dest];
}
enum Type { EXIT, HOLE, STONE, GRASS };
Type maze[30][30];
int rows;
int cols;
inline int Node(int r, int c)
{
return r * cols + c;
}
SSSP sssp;
void Solve()
{
fill(maze[0], maze[30], GRASS);

scanf("%d%d", &rows, &cols);
if(rows == 0 && cols == 0)
exit(0);

sssp.Init(rows * cols);

int stones;
scanf("%d", &stones);
while(stones-- > 0)
{
int r, c;
scanf("%d%d", &r, &c);
maze[r][c] = STONE;
}

int holes;
scanf("%d", &holes);

while(holes-- > 0)
{
int r0, c0, r1, c1, t;
scanf("%d%d%d%d%d", &r0, &c0, &r1, &c1, &t);
sssp.NewEdge(Node(r0, c0), Node(r1, c1), t);
maze[r0][c0] = HOLE;
}

maze[rows - 1][cols - 1] = EXIT;

for(int i=0; i<rows; ++i)
{
for(int k=0; k<cols; ++k)
{
if(maze[i][k] != GRASS)
continue;

static int dr[] = {1, -1, 0, 0};
static int dc[] = {0, 0, 1, -1};

for(int d=0; d<4; ++d)
{
int r = i + dr[d];
int c = k + dc[d];

if(0 <= r && r < rows && 0 <= c && c < cols && maze[r][c] != STONE)
sssp.NewEdge(Node(i, k), Node(r, c), 1);
}
}
}

int spfa = sssp.SPFA(Node(0, 0), Node(rows - 1, cols - 1));

if(spfa == INF)
printf("Impossible/n");
else if(spfa == -INF)
printf("Never/n");
else
printf("%d/n", spfa);
}
int main()
{
while(true)
Solve();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: