题目链接

Dijkstra(DP)

类型题 :[UVA - 10269](https://www.cnblogs.com/AsuraS/articles/11128037.html)

状态dp[i][j] 表示的是从起点到当前节点i时,是否用了免去最贵票的机会,j == 0表示已用,j == 1表示还没用。
那么存在3种状态转移

  1. dp[v][0] = dp[u][1]+G[u][v]-maxn[v]
  2. dp[v][0] = dp[u][0]+G[u][v]
  3. dp[v][1] = dp[u][1]+G[u][v];

maxn[i] 表示的是从起点到当前节点i的途中,最贵的票是多少

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <stack>
#include <map>

using namespace std;

const int INF = 0x3f3f3f3f;
const int Maxn = 200+10;

struct Node {
	int i, j, w;
	Node(int x, int y, int z):i(x), j(y), w(z){
	}
	bool operator < (const Node a1) const {
		return w > a1.w;
	}
};

int G[Maxn][Maxn], dp[Maxn][2], maxn[Maxn];
bool vis[Maxn][2];

void Dij(int s, int t, int n) {
	for(int i = 0; i < n; ++i) {
		dp[i][0] = dp[i][1] = INF;
		vis[i][0] = vis[i][1] = false;
		maxn[i] = 0;
	}
	dp[s][1] = 0;
	vis[s][0] = true;
	priority_queue <Node> qu;
	qu.push(Node(s, 1, 0));
	
	while(!qu.empty()) {
		Node u = qu.top(); qu.pop();
		if(vis[u.i][u.j]) continue;
		vis[u.i][u.j] = true;
		
		for(int i = 0; i < n; ++i) {
			if(G[u.i][i] != INF) {
				maxn[i] = max(maxn[u.i], G[u.i][i]);
				if(dp[i][0] > dp[u.i][0]+G[u.i][i]) {
					dp[i][0] = dp[u.i][0]+G[u.i][i];
					qu.push(Node(i, 0, dp[i][0]));	
				}
				if(dp[i][0] > dp[u.i][1]+G[u.i][i]-maxn[i]) {
					dp[i][0] = dp[u.i][1]+G[u.i][i]-maxn[i];
					qu.push(Node(i, 0, dp[i][0]));
				}
				if(dp[i][1] > dp[u.i][1]+G[u.i][i]) {
					dp[i][1] = dp[u.i][1]+G[u.i][i];
					qu.push(Node(i, 1, dp[i][1]));	
				}
			}
		}
	}
	cout << min(dp[t][0], dp[t][1]) << endl;
}

int main(void)
{
	string s, t;
	while(cin >> s >> t) {
		int n, index = 0;
		map <string, int> mp;
		mp[s] = index++; mp[t] = index++;
		cin >> n;
		string u, v; int w;
		memset(G, INF, sizeof(G));
		for(int i = 0; i < n; ++i) {
			cin >> u >> v >> w;
			if(mp.find(u) == mp.end()) mp[u] = index++;
			if(mp.find(v) == mp.end()) mp[v] = index++;
			int x = mp[u], y = mp[v];
			G[x][y] = min(G[x][y], w);
		}
		Dij(mp[s], mp[t], index);
	}
	return 0;
 }