POJ2387

好好一道Dijkstra模板题,瞎敲了一种方法

复杂度O(nlogn),排序*点数

原本一直wa,经大佬点播要多次排序

深夜扭出一组数据,发现不排序会错:节点2未连接

5 10
1 10 4
2 4 8
4 6 2
6 2 1
4 10 3

以后还是用模板的写法吧。。大佬说图论不要瞎敲

思路如下:2层循环,i指过的地方表示最短路已建立,j以i为中继点向后移动进行松弛

这里就要求i指的一定是到源点最短的一个点,所以每次变动i都要再对数组进行排序

代码如下:

#define inf 0x3f3f3f3f
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;

struct spot {
	int id;
	int d;
};

int cmp(spot a, spot b) {
	return a.d < b.d;
}

int chart[1001][1001];//chart[i][j]:i到j的距离
spot dis[1001];			//dis[i]:i到1的距离
int ans[1001];

int main() {
	int t, n;
	while (~scanf("%d %d", &t, &n)) {
		memset(chart, 0, sizeof(chart));
		for (int i = 1; i <= n; i++) {
			dis[i].d = inf;
			dis[i].id = i;
		}
		dis[1].d = 0;
		for (int i = 1; i <= t; i++) {
			int x, y, z;
			scanf("%d %d %d", &x, &y, &z);
			if (chart[x][y] && chart[x][y] <= z) {continue;}
			chart[x][y] = chart[y][x] = z;
			if (x == 1) { dis[y].d = z; } 
			else if (y == 1) { dis[x].d = z; }
		}

		sort(dis+1, dis + n +1,cmp);

		for (int i = 1; i <= n; i++) {
			//if (dis[i].id == n) {
			//cout << dis[i].id << "_________" << dis[i].d << endl;
			//}
		}
		//cout << endl;
		for (int i = 2; i <= n; i++) {	//cmp[i].d存储i到1的最短距离
			sort(dis + 1, dis + n + 1, cmp);
			int sure = dis[i].id;
			
			for (int j = i ; j <= n; j++) {	
				
				int temp = dis[j].id;
				if (chart[sure][temp]) {
					dis[j].d = min(dis[j].d, dis[i].d + chart[temp][sure]);
					//cout << dis[j].id << "___________" << dis[j].d << endl;
					//cout << "link  " << sure << "  to " << temp << endl;
				}
			}
			
		}	
		//cout << endl;
		for (int i = 1; i <= n; i++) {
			if (dis[i].id == n) {
				//cout <<dis[i].id<<"_________"<<dis[i].d << endl;
				cout << dis[i].d;
			}
		}
	}
	
}

posted @ 2017-01-17 00:36  Drenight  阅读(166)  评论(0编辑  收藏  举报