您的位置:首页 > 其它

shortest path

2018-02-08 19:27 225 查看
今天做了hdu4479的一道题,是要求找到单源最短路径,同时路径上的边的距离需要是严格单调递增的。乍一看其已经不再符合贪心的结构,不能用dijkstra来直接处理。这里感觉要换下思路,即将建立单源最短路的过程看成是一个集合的扩张过程,其中通过保证扩张的过程是从边权递增的顺序进行以完成扩展,同时在每一轮中进行相应处理判断即可。另外确实要学习更多stl的巧妙用法了。#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <utility>
using namespace std;
#define MAXN 10003
#define INF 1e18
typedef long long ll;
typedef struct vertex {
ll length;
struct vertex(ll lengtho) { length = lengtho; }
}Vertex;
typedef struct edge {
int fromCity;
int toCity;
ll length;
struct edge(int fromCit, int toCit, ll wei) { fromCity = fromCit; toCity = toCit; length = wei; }
bool operator < (const struct edge& a){ return length < a.length; }
}Edge;

int T, N, M;
vector<Edge > edges;
vector<Vertex > vertices;

void init()
{
edges.clear();
vertices.clear();
}
void input()
{
scanf("%d %d", &N, &M);
int city1, city2;
ll weight;
for (int i = 0; i < M; i++) {
scanf("%d %d %lld", &city1, &city2, &weight);
assert(city1 <= N&&city2 <= N);
edges.push_back(Edge(city1 - 1, city2 - 1, weight));
}
sort(edges.begin(), edges.end());
}
void betterRelax(int left, int rigt)
{
//printf("Relaxing between %d and %d\n", left, rigt);
vector<pair<int, ll>> updateList;
for (int i = left; i <= rigt; i++) {
Edge temp = edges[i];
int u = temp.fromCity;
int v = temp.toCity;
if (vertices[u].length != INF&&vertices[v].length > vertices[u].length + temp.length)
updateList.push_back(make_pair(v, vertices[u].length + temp.length));
if (vertices[v].length != INF&&vertices[u].length > vertices[v].length + temp.length)
updateList.push_back(make_pair(u, vertices[v].length + temp.length));
}
for (int i = 0; i < updateList.size(); i++) {
pair<int, ll> &temp = updateList[i];
vertices[temp.first].length = min(vertices[temp.first].length, temp.second);
}
}
void increasingShortestPath()
{
for (int i = 0; i < N; i++)
vertices.push_back(Vertex(INF));
vertices[0].length = 0;
int j;
for (int i = 0; i < edges.size(); ) {
for (j = i + 1; j < edges.size(); j++)
if (edges[j].length > edges[i].length)
break;
betterRelax(i, j - 1);
i = j;
}
if (vertices[N - 1].length >= INF)
printf("No answer\n");
else
printf("%lld\n", vertices[N - 1].length);
}
int main()
{
scanf("%d", &T);
for (int i = 0; i < T; i++) {
init();
input();
increasingShortestPath();
}
return 0;
}
(注:本题解题思路受http://blog.csdn.net/cquwel启发,在此表示领教了)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  single source shortest path