POJ:1511 Invitation Cards(双向搜索最短路径)

POJ :1511 http://poj.org/problem?id=1511

思路

  • 求1号点到其他点的最短路 + 其他点到1号点的最短。 结果用long long。
  • 快读可以加快时间

代码

  • spfa 890ms
#ifdef ONLINE_JUDGE
#pragma warning (disable : 4996)
#endif // ONLINE_JUDHE
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int N = 1e6 + 10, M = 2e6 + 10, inf = 0x3f;
struct Edge {
	int v, w, next;
}e[M];
int n, m, t, u, v, w, len, h[N], rh[N], d[N], rd[N]; //rh[]是反向建图 
bool book[N];

inline int read() {
	int s = 0, w = 1;
	char ch = getchar();
	while (ch<'0' || ch>'9') { if (ch == '-')w = -1; ch = getchar(); }
	while (ch >= '0'&&ch <= '9') s = s * 10 + ch - '0', ch = getchar();
	return s * w;
}

void add(int h[], int u, int v, int w) {
	e[len].w = w;
	e[len].v = v;
	e[len].next = h[u];
	h[u] = len++;
}

void spfa(int d[], int h[]) {
	memset(d, 0x3f, sizeof(rd));
	d[1] = 0;
	queue<int> q;
	q.push(1);
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		book[u] = false;
		for (int j = h[u]; j; j = e[j].next) {
			int v = e[j].v;
			int w = d[u] + e[j].w;
			if (d[v] > w) {
				d[v] = w;
				if (!book[v]) q.push(v), book[v] = true;
			}
		}
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	int T;
	cin >> T;
	while (T--) {
		memset(h, 0, sizeof(h)); len = 1;
		memset(rh, 0, sizeof(rh));
		cin >> n >> m;
		for (int i = 1; i <= m; ++i) {
			u = read(); v = read(); w = read();
			add(h, u, v, w);
			add(rh, v, u, w);
		}
		spfa(d, h);//求1回其他各点的最短路 
		spfa(rd, rh);//求其他各点到1的最短路
		long long ans = 0;
		for (int i = 1; i <= n; ++i)ans += d[i] + rd[i];
		cout << ans << endl;

	}
#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	system("out.txt");
#endif // !ONLINE_JUDGE
	return 0;
}

  • Djkstra 2125ms...
#ifdef ONLINE_JUDGE
#pragma warning (disable : 4996)
#endif // ONLINE_JUDHE
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int N = 1e6 + 10, M = 2e6 + 10, inf = 0x3f;
struct Edge {
	int v, w, next;
}e[M];
struct Node {
	int d, v;
	Node(int d,int v): d(d),v(v){}
	Node(){}
	bool operator < (const Node & w)const {
		return d > w.d;
	}
};
int n, m, t, u, v, w, len, h[N], rh[N], d[N], rd[N]; //rh[]是反向建图
bool book[N];

void add(int h[], int u, int v, int w) {
	e[len].w = w;
	e[len].v = v;
	e[len].next = h[u];
	h[u] = len++;
}

void djkstra(int d[], int h[]) {
	memset(d, 0x3f, sizeof(rd));
	memset(book, false, sizeof(book));
	d[1] = 0;
	priority_queue<Node> q;
	q.push(Node(0, 1));
	while (!q.empty()) {
		int u = q.top().v;
		q.pop();
		if (book[u]) continue;
		book[u] = true;
		for (int j = h[u]; j; j = e[j].next) {
			int v = e[j].v;
			int w = d[u] + e[j].w;
			if (d[v] > w) {
				d[v] = w;
				q.push(Node{ d[v],v });
			}
		}
	}
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	scanf("%d", &t);
	while (t--) {
		memset(h, 0, sizeof(h)); len = 1;
		memset(rh, 0, sizeof(rh));
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= m; i++) {
			scanf("%d%d%d", &u, &v, &w);
			add(h, u, v, w);
			add(rh, v, u, w);
		}
		djkstra(d, h); //求1回其他各点的最短路 
		djkstra(rd, rh);//求其他各点到1的最短路
		long long  ans = 0;
		for (int i = 1; i <= n; i++) ans += d[i] + rd[i];
		printf("%lld\n", ans);
	}
#ifndef ONLINE_JUDGE
	fclose(stdin);
	fclose(stdout);
	system("out.txt");
#endif // !ONLINE_JUDGE
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/RioTian/p/12926394.html