SPFA+前向星统计最短路条数

版权声明:博主的博客不值钱随便转载但要注明出处 https://blog.csdn.net/easylovecsdn/article/details/86562036

题目:洛谷P1608 路径统计,地址:https://www.luogu.org/problemnew/show/P1608

//#pragma gcc optimize(3)
#include <bits/stdc++.h>
#define MAX 4000005
#define _MAX 2005
#define INF (1<<30)
using namespace std;
#define max(a, b) (a>b?a:b)
#define min(a, b) (a<b?a:b)

struct edge { int to, next, w; };
edge es[MAX];
int v, e, cnt;
int head[MAX], d[MAX], path[MAX],s[_MAX][_MAX];
bool used[MAX];
int ypa[MAX];

void add(int u, int v, int w)
{
	es[++cnt].to = v;
	es[cnt].w = w;
	es[cnt].next = head[u];
	head[u] = cnt;
}

void spfa(int st)
{
	for (int i = 1; i <= max(v, e); i++) {
		used[i] = 0;
		d[i] = INF;
		path[i] = 0;
		ypa[i] = 0;
	}
	queue<int> q;
	q.push(st);
	used[st] = 1;
	d[st] = 0;
	ypa[st] = path[st] = 1;
	while (!q.empty()) {
		int t = q.front();
		q.pop();
		used[t] = 0;
		if (t == v)
			continue;
		for (int i = head[t]; i; i = es[i].next) {
			int temp = es[i].to;
			if (d[temp] >= d[t] + es[i].w) {
				if (d[temp] == d[t] + es[i].w) {
					path[temp] += ypa[t];
					ypa[temp] += ypa[t];
				}
				else {
					path[temp] = ypa[t];
					ypa[temp] = ypa[t];
				}
				d[temp] = d[t] + es[i].w;
				if (!used[temp]) {
					q.push(temp);
					used[temp] = 1; 
				}
			}
		}
		ypa[t] = 0;
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin >> v >> e;
	memset(s, 0, sizeof(s));
	for (int i = 0; i < e; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		if (s[u][v] == w) continue;
		s[u][v] = w;
		add(u, v, w);
	}
	
	spfa(1);
	if (d[v] == INF)
		cout << "No answer" << endl;
	else
		cout << d[v] << " " << path[v] << endl;
	return 0;
}

友情数据

input1
5 6
1 2 1
2 3 1
1 3 2
1 4 3
3 4 1
4 5 5

output1
8 3

input2
5 5
1 2 1
2 3 1
3 4 1
4 5 1
1 4 3

output2
4 2

input3
6 12
1 2 1
2 3 1
3 2 1
3 4 1
4 3 1
4 5 1
2 5 1
5 2 1
5 4 1
4 6 1
5 6 2
3 6 2

output3
4 4

input4
5 7
1 2 1
2 3 1
1 3 2
1 4 3
3 4 1
4 5 5
3 5 6

output4
8 5

猜你喜欢

转载自blog.csdn.net/easylovecsdn/article/details/86562036
今日推荐