POJ 1062 有限制条件的最短路
见到得POJ第一道中文题。
刚开始算法想错了,交上去果断WA
刚开始错误得算法:
1. 根据题意建好图
2.floyd求传递闭包。
3.以1为起点,求一次Dijsktra算法,并记录其路径
4.枚举1可以到的点,求出其最小直,并判断该路径上得点是否满足等级限制
交上去错了后,才发现算法错了。。
1 4 10000 3 2 2 1 3 3 1000 2 2 4 1 3 1 1000 3 1 4 2 100 4 0
这组数据就能完全否认我的算法。并且改不过来。果断换算法。
看了discuss,有人说,枚举等级限制,求多次Dijkstra,很暴力,但毫无疑问时正确的算法。
正确算法如下:
1.建好图
2.枚举等级,如果酋长等级是4,限制为2,那么等级区间为2-4,3-5,4-6
3.求最短路
写好后,又Wa了,dis[v] > dis[k] + w 没有加dis[k] != inf 悲剧。
View Code
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <algorithm> using namespace std; #define MAXN 501000 struct Edge { int u, next, val; Edge() { } Edge( int U, int Next, int Val): u(U), next(Next), val(Val) { } }edge[MAXN]; const int inf = 0x7f7f7f7f; int M, N, head[MAXN], dis[MAXN], visit[MAXN], size; int rank[110]; //该点等级 int price[110]; //该点价格 int limit[110];//等级限制 int out[110]; //该点的出度,也就是替代品总数 void init( ) { for( int i = 0; i <= N; i++) { head[i] = -1; price[i] = 0; rank[i] = 0; out[i] = 0; } size = 0; } void AddEdge( int u, int v, int val) { edge[size] = Edge(v, head[u], val); head[u] = size++; } //求最短路Dijsktra算法 int dij( ) { for( int i = 1; i <= N; i++) { dis[i] = inf; visit[i] = 0; } dis[1] = 0; for( int i = 1; i <= N; i++) { int oo = inf, k = 0; for( int j = 1; j <= N; j++) { if( !visit[j] && dis[j] < oo && limit[j]) { oo = dis[j]; k = j; } } visit[k] = 1; for( int e = head[k]; e != -1; e = edge[e].next ) { int v = edge[e].u; int w = edge[e].val; if(!visit[v] && dis[v] > dis[k] + w && limit[v] && dis[k] != inf) { dis[v] = dis[k] + w; } } } int oo = inf; for( int i = 1; i <= N; i++) { dis[i] += price[i]; if( oo > dis[i] ) oo = dis[i]; } return oo; } int main( ) { int a, b; scanf("%d%d", &M, &N); init( ); for( int i = 1; i <= N; i++) { scanf("%d%d%d", &price[i], &rank[i],&out[i]); for( int j = 1; j <= out[i]; j++) { scanf("%d%d",&a, &b); AddEdge( i, a, b); } } int ans = rank[1], minxx = inf; for( int i = 0; i <= M; i++) { memset(limit, 0, sizeof(limit)); for( int j = 1; j <= N; j++) if( rank[j] >= ans - M + i && rank[j] <= ans + i ) limit[j] = 1; int minx = dij( ); minxx = min( minx, minxx); } printf("%d\n",minxx); return 0; }
posted on 2012-07-11 19:05 more think, more gains 阅读(260) 评论(0) 编辑 收藏 举报