DIjkstra(反向边) POJ 3268 Silver Cow Party || POJ 1511 Invitation Cards

题目传送门 1 2

题意:有向图,所有点先走到x点,在从x点返回,问其中最大的某点最短路程

分析:对图正反都跑一次最短路,开两个数组记录x到其余点的距离,这样就能求出来的最短路以及回去的最短路.

POJ 3268

//#include <bits/stdc++.h>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;

typedef long long ll;
const int N = 1e6 + 5;
const int E = N;
const int INF = 0x3f3f3f3f;
struct Edge	{
	int u, v, w, nex;
	Edge() {}
	Edge(int u, int v, int w, int nex) : u (u), v (v), w (w), nex (nex) {}
	bool operator < (const Edge &r)	const	{
		return w > r.w;
	}
}edge[2][E];
int head[N];
int d[2][N];
bool vis[N];
int n, m, x, e;

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

void init(void)	{
	memset (head, -1, sizeof (head));
	e = 0;
}

void add_edge(int u, int v, int w)	{
	edge[0][e] = Edge (u, v, w, head[u]);
	head[u] = e++;
}

void build_re_graph(void)	{
	memset (head, -1, sizeof (head));
	e = 0;
	for (int i=0; i<m; ++i)	{
		edge[1][e] = Edge (edge[0][i].v, edge[0][i].u, edge[0][i].w, head[edge[0][i].v]);
		head[edge[0][i].v] = e++;
	}
}

void SPFA(int s, int tp)	{
	memset (d[tp], INF, sizeof (d[tp]));
	memset (vis, false, sizeof (vis));
	d[tp][s] = 0;	vis[s] = true;
	queue<int> que;	que.push (s);
	while (!que.empty ())	{
		int u = que.front ();	que.pop ();
		vis[u] = false;
		for (int i=head[u]; ~i; i=edge[tp][i].nex)	{
			int v = edge[tp][i].v, w = edge[tp][i].w;
			if (d[tp][v] > d[tp][u] + w)	{
				d[tp][v] = d[tp][u] + w;
				if (!vis[v])	{
					vis[v] = true;	que.push (v);
				}
			}
		}
	}
}

void Dijkstra(int s, int tp)	{
	memset (vis, false, sizeof (vis));
	memset (d[tp], INF, sizeof (d[tp]));	d[tp][s] = 0;
	priority_queue<Edge> que;	que.push (Edge (0, s, d[tp][s], 0));
	while (!que.empty ())	{
		int u = que.top ().v;	que.pop ();
		if (vis[u])	continue;
		for (int i=head[u]; ~i; i=edge[tp][i].nex)	{
			int v = edge[tp][i].v, w = edge[tp][i].w;
			if (!vis[v] && d[tp][v] > d[tp][u] + w)	{
				d[tp][v] = d[tp][u] + w;	que.push (Edge (0, v, d[tp][v], 0));
			}
		}
	}
}

int get_max(void)	{
	int ret = 0;
	for (int i=1; i<=n; ++i)	{
		ret = max (ret, d[0][i] + d[1][i]);
	}
	return ret;
}

int main(void)	{
	while (scanf ("%d%d%d", &n, &m, &x) == 3)	{
		init ();
		for (int u, v, w, i=0; i<m; ++i)	{
			scanf ("%d%d%d", &u, &v, &w);
			add_edge (u, v, w);
		}
		//SPFA (x, 0);
		Dijkstra (x, 0);
		build_re_graph ();
		//SPFA (x, 1);
		Dijkstra (x, 1);
		int ans = get_max ();
		printf ("%d
", ans);
	}

	return 0;
}

还有一道类似的题目,是求最大和,其实都是一样的

POJ 1511 

//#include <bits/stdc++.h>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;

typedef long long ll;
const int N = 1e6 + 5;
const int E = N;
const int INF = 0x3f3f3f3f;
struct Edge	{
	int u, v, w, nex;
	Edge() {}
	Edge(int u, int v, int w, int nex) : u (u), v (v), w (w), nex (nex) {}
	bool operator < (const Edge &r)	const	{
		return w > r.w;
	}
}edge[2][E];
int head[N];
int d[N];
bool vis[N];
int n, m, e;

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

void init(void)	{
	memset (head, -1, sizeof (head));
	e = 0;
}

void add_edge(int u, int v, int w)	{
	edge[0][e] = Edge (u, v, w, head[u]);
	head[u] = e++;
}

void build_re_graph(void)	{
	memset (head, -1, sizeof (head));
	e = 0;
	for (int i=0; i<m; ++i)	{
		edge[1][e] = Edge (edge[0][i].v, edge[0][i].u, edge[0][i].w, head[edge[0][i].v]);
		head[edge[0][i].v] = e++;
	}
}

void SPFA(int s, int tp)	{
	memset (d, INF, sizeof (d));
	memset (vis, false, sizeof (vis));
	d[s] = 0;	vis[s] = true;
	queue<int> que;	que.push (s);
	while (!que.empty ())	{
		int u = que.front ();	que.pop ();
		vis[u] = false;
		for (int i=head[u]; ~i; i=edge[tp][i].nex)	{
			int v = edge[tp][i].v, w = edge[tp][i].w;
			if (d[v] > d[u] + w)	{
				d[v] = d[u] + w;
				if (!vis[v])	{
					vis[v] = true;	que.push (v);
				}
			}
		}
	}
}

ll get_sum(void)	{
	ll ret = 0;
	for (int i=1; i<=n; ++i)	{
		ret += d[i];
	}
	return ret;
}

int main(void)	{
	int T;	scanf ("%d", &T);
	while (T--)	{
		scanf ("%d%d", &n, &m);
		init ();
		for (int u, v, w, i=0; i<m; ++i)	{
			//scanf ("%d%d%d", &u, &v, &w);
			u = read ();	v = read ();	w = read ();
			add_edge (u, v, w);
		}
		SPFA (1, 0);
		ll ans = get_sum ();
		build_re_graph ();
		SPFA (1, 1);
		ans += get_sum ();
		printf ("%lld
", ans);
	}

	return 0;
}

  

编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/5001609.html