hdu3499---玄学的分层图

枚举固然可以,但是我还是想看看分层图。。。。

如本题所述 ,从上图到下图就是一个折扣的过程,上部分只有一种办法下去,下部分图没有办法去上面,该模型十分的巧妙啊!!!

下面我来演示一下自己改的样例吧

紫色路线是最短的,从上往下的路就是打折的路,类似bfs搜索,上面的所有点都可以下来,但是dijkstra只会只会保留最优的解

#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<map>
#include<string>
using namespace std;
#define maxn 500000+10
typedef long long ll;
const long long INF = 2e14;
struct Node {
	int p, tmp;
	ll val;
	Node(int a, ll b,int t) :p(a), val(b),tmp(t) {}
};
int n, m;
vector<Node>G[maxn];
bool operator < (const Node a, const Node b) {
	if (a.val > b.val) return true;
	else return false;
}
int vis[maxn][2];
ll dis[maxn][2];
void insert(int be, int en, ll len) {
	G[be].push_back(Node(en, len, 0));
	G[be].push_back(Node(en, len, 1));
	return;
}
int dijkstra(int be) {
	priority_queue<Node>que;
	for (int i = 0; i <= n; i++) {
		for (int j = 0; j < 2; j++) {
			vis[i][j] = 0;
			dis[i][j] = INF;
		}
	}
	dis[be][0] = 0;
	dis[be][1] = 0;
	que.push(Node(be, 0, 0));
	while (!que.empty()) {
		Node ans = que.top();
		que.pop();
		if (vis[ans.p][ans.tmp] == 0) {
			vis[ans.p][ans.tmp] = 1;
			for (int i = 0; i < G[ans.p].size(); i++) {
				int p = G[ans.p][i].p;
				int t = G[ans.p][i].tmp;//确定位置
				if (!vis[p][t] && dis[p][t] > dis[ans.p][t] + G[ans.p][i].val) {
					dis[p][t] = G[ans.p][i].val + dis[ans.p][t];
					que.push(Node(p, dis[p][t], t));
				}
				
				if (t == 0) {//可以下来的话
					if (!vis[p][1] && dis[p][1] > dis[ans.p][0] + G[ans.p][i].val / 2) {//从上面穿下来所以是0加给1
						dis[p][1] = dis[ans.p][0] + G[ans.p][i].val/2;
						que.push(Node(p, dis[p][1], 1));
					}
				}
			}
		}
	}
	return 0;
}
map<string, int>ins;
int main() {
	while (~scanf("%d %d", &n, &m)) {
		ins.clear();
		for (int i = 0; i <= n; i++)G[i].clear();
 		string be, en;
		ll len;
		int cnt = 1;
		while (m--) {
			cin >> be >> en;
			scanf("%lld", &len);
			if (ins[be] == 0) ins[be] = cnt++;
			if (ins[en] == 0) ins[en] = cnt++;
			insert(ins[be], ins[en], len);
		}
		cin >> be >> en;
		if (ins[be] == 0) ins[be] = cnt++;
		if (ins[en] == 0) ins[en] = cnt++;
		dijkstra(ins[be]);
		if (dis[ins[en]][1] == INF) printf("-1
");
		else printf("%lld
", dis[ins[en]][1]);
	}
	return 0;
}

  

寻找真正的热爱
原文地址:https://www.cnblogs.com/lesning/p/11346181.html