histcat

histcat

P1875 Jiajia's Magic Potion

Problem#

link

Solution#

Seeing this problem, it looks very much like dynamic programming (dp).

However, it may have cycles, so we cannot use dp. Since all values are positive, we can consider using Dijkstra's algorithm to perform "dp".

Dijkstra#

It is important to note that when performing Dijkstra's algorithm, an edge x->y can only update other points if both x and y have determined their minimum values. Otherwise, if some points are initialized as minimum values, the number of ways to compute them will be counted multiple times.

Code#

#include<bits/stdc++.h>

using namespace std;

const int N = 1100;
int dis[N];
bool vis[N];
int num[N], g[N][N], n;
int main()
{
	scanf("%d", &n);
	for(int i = 1;i <= n;i++)
		scanf("%d", &dis[i]);
	int a, b, c;
	for(int i = 1;i <= n;i++) num[i] = 1;
	while(scanf("%d%d%d", &a, &b, &c) != EOF)
	{
		a++, b++;
		g[a][b] = g[b][a] = c + 1;
	}
	dis[0] = 0x3f3f3f3f;
	while(1)
	{
		int x = 0;
		for(int i = 1;i <= n;i++)
		{
			if(!vis[i] && dis[i] < dis[x])
				x = i;
		}
		if(x == 0)
		{
			break;
		}
		vis[x] = 1;
		for(int y = 1;y <= n;y++)
		{
			if(g[x][y] == 0 || !vis[y]) continue;
			if(dis[g[x][y]] == dis[x] + dis[y])
			{
				num[g[x][y]] += num[x] * num[y];
			}
			else if(dis[g[x][y]] > dis[x] + dis[y])
			{
				dis[g[x][y]] = dis[x] + dis[y];
				num[g[x][y]] = num[x] * num[y];
			}
		}
	}
	cout << dis[1] << " " << num[1];
	return 0;
}

SPFA#

The sdsc 2022 day6 lecture notes have discussed this.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.