POJ 3169 Layout BellmanFord Dijkstra

一、心路历程

这一个题目写了三天,可以说是非常挣扎了,明明是例题,但是就是倔强着不去看书上的题解,WA了7次,TLE了4次。

POJ 3169 Layout BellmanFord Dijkstra_第1张图片

 写了不知道多少条测试用例,一遍一遍的过,一点一点的调试。

POJ 3169 Layout BellmanFord Dijkstra_第2张图片

 最后终于找到了规则

二、思路

1、题目要求1到N,必须按照顺序排,那么我们就可以认为 对每个 i >1,存在 i -1 到 i 的 0 的斥力

2、我们每一条A到B的排斥力P,看作B到A引力力 P * (-1)

3、规则1中 斥力,和 输入的斥力,都按照第二条规则,转化引力,然后不考虑斥力

4、用 BellmanFord算法,对转换成的和输入的引力集合,判断是否存在负圈,存在直接输出-1

5、不存在负圈,则直接对转换成的和输入的引力集合使用dijkstra算法,起点是1,如果d[N]大于1000000007(每条边最大值乘以边数,加7是为了防止边界出错),则输出-2,否则输出d[N]。

三、代码

#include 
#include 
#include 
using namespace std;
struct Node
{
    int from, to, cost;
    Node(int from = 0, int to = 0, int cost = 0) : from(from), to(to), cost(cost) {}
};
vector nodes;
typedef pair P;
vector

edges[1007]; int d[1007], N, inf = 0x3f3f3f3f, ML, MD, area[1007][1007]; bool used[1007]; void input() { int from, to, cost; for (int i = 1; i <= ML; i++) { scanf("%d%d%d", &from, &to, &cost); edges[from].push_back(P(cost, to)); nodes.push_back(Node(from, to, cost)); } for (int i = 1; i <= MD; i++) { scanf("%d%d%d", &from, &to, &cost); edges[to].push_back(P(-cost, from)); nodes.push_back(Node(to, from, -cost)); } for (int i = 2; i <= N; i++) { edges[i].push_back(P(0, i - 1)); nodes.push_back(Node(i, i - 1, -1)); } } bool bellmanFord(int s) { bool flag = false; for (int i = 1; i <= N; i++) { d[i] = inf; } d[s] = 0; for (int i = 1; i <= N; i++) { for (int j = 0; j < nodes.size(); j++) { if (d[nodes[j].from] + nodes[j].cost < d[nodes[j].to]) { d[nodes[j].to] = d[nodes[j].from] + nodes[j].cost; if (i == N) { flag = true; } } } } return flag; } void dijkstra(int s) { for (int i = 1; i <= N; i++) { d[i] = inf; used[i] = false; } d[s] = 0; priority_queue, greater

> que; que.push(P(0, s)); while (!que.empty()) { P current = que.top(); que.pop(); if (used[current.second] || current.first > d[current.second]) { continue; } for (int i = 0; i < edges[current.second].size(); i++) { P toEdge = edges[current.second][i]; if (d[current.second] + toEdge.first < d[toEdge.second]) { d[toEdge.second] = toEdge.first + d[current.second]; que.push(P(d[toEdge.second], toEdge.second)); } } } } void solve() { if (bellmanFord(1)) { printf("%d\n", -1); } else { dijkstra(1); if (d[N] > 1000000007) { printf("%d\n", -2); } else { printf("%d\n", d[N]); } } } int main() { scanf("%d%d%d", &N, &ML, &MD); input(); solve(); return 0; }

 

你可能感兴趣的:(算法,图论,数据结构)