shortest path

今天做了hdu4479的一道题,是要求找到单源最短路径,同时路径上的边的距离需要是严格单调递增的。乍一看其已经不再符合贪心的结构,不能用dijkstra来直接处理。这里感觉要换下思路,即将建立单源最短路的过程看成是一个集合的扩张过程,其中通过保证扩张的过程是从边权递增的顺序进行以完成扩展,同时在每一轮中进行相应处理判断即可。另外确实要学习更多stl的巧妙用法了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
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 edges;
vector 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> 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 &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,oj,odyssey)