例题6-20 理想路径(Ideal Path, NEERC 2010, UVa1599)

来源:互联网 发布:ubuntu完美精简版 编辑:程序博客网 时间:2024/04/29 00:07
1. 若不考虑字典序问题,则显然可以直接bfs求解最短路。但是如何使得字典序最小呢?
2. 显然要贪心选取每一步的col值最小,为了保证贪心选取时每一步都仍为最短路,从终点进行一次bfs的到各点dis。
3. 取最小值的过程仍为bfs的过程,但是需要从多点出发访问下一层的bfs,用vector来实现,且访问层数即为最短距离。
#include <iostream>#include <string>#include <vector>#include <stack>#include <queue>#include <deque>#include <set>#include <map>#include <algorithm>#include <functional>#include <utility>#include <cstring>#include <cstdio>#include <cstdlib>#include <ctime>#include <cmath>#include <cctype>#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define LL long long#define maxn 100005#define maxm 200005#define mod 1000000007#define INF 1000000007#define eps 1e-5#define PI 3.1415926535898#define N 26using namespace std;//-------------------------CHC------------------------------//struct Edge {int to, col;Edge(int to = 0, int col = 0) : to(to), col(col) { }};vector<Edge> edges[maxn];int d[maxn];bool vis[maxn];vector<int> col;void get_dis(int n) {CLEAR(vis, 0);queue<int> q;q.push(n);vis[n] = true;d[n] = 0;while (q.size()) {int u = q.front(); q.pop();for (int i = 0; i < edges[u].size(); ++i) {int v = edges[u][i].to;if (!vis[v]) {vis[v] = true;d[v] = d[u] + 1;q.push(v);}}}}void bfs(int n) {CLEAR(vis, 0);col.clear();vector<int> s;s.push_back(1);vis[1] = true;for (int i = 0; i < d[1]; ++i) {int mincol = INF;for (int j = 0; j < s.size(); ++j) {//find the minimum colint u = s[j];for (int k = 0; k < edges[u].size(); ++k) {int v = edges[u][k].to, c = edges[u][k].col;if (!vis[v] && d[v] == d[u] - 1)mincol = min(mincol, c);}}col.push_back(mincol);vector<int> temp;for (int j = 0; j < s.size(); ++j) {//find out the next vertices of the next phaseint u = s[j];for (int k = 0; k < edges[u].size(); ++k) {int v = edges[u][k].to, c = edges[u][k].col;if (!vis[v] && d[v] == d[u] - 1 && c == mincol) {temp.push_back(v);vis[v] = true;}}}s = temp;}}int main() {int n, m;while (~scanf("%d%d", &n, &m)) {for (int i = 1; i <= n; ++i) edges[i].clear();CLEAR(d, -1);int u, v, w;for (int i = 0; i < m; ++i) {scanf("%d%d%d", &u, &v, &w);edges[u].push_back(Edge(v, w));edges[v].push_back(Edge(u, w));}get_dis(n);bfs(n);printf("%d\n", d[1]);bool first = true;for (int i = 0; i < col.size(); ++i) {if (first) first = false;else putchar(' ');printf("%d", col[i]);}putchar('\n');}return 0;}

原创粉丝点击