【例题 6-20 UVA - 1599】Ideal Path

【链接】 我是链接,点我呀:)
【题意】

在这里输入题意

【题解】

逆向做一遍bfs.
得到终点到某个点的最短距离。
这样,我们从起点顺序的时候。
就能知道最短路的下一步是要走哪里了。
这样,我们从起点也开始做一遍bfs.
然后根据逆序的bfs得知下一步该往哪些点走。
每次优先走最小的字典序边即可。
多个最小的,就每个都走一遍试试。
6 6
1 2 3
1 3 3
2 4 5
3 5 1
4 6 1
5 6 100
↑↑这组数据可以hack网上好多人(>=1)的做法。
如果出现前一段路不是最小字典序了,就要结束这一段路了,不能继续往下走。

【代码】

/*
    1.Shoud it use long long ?
    2.Have you ever test several sample(at least therr) yourself?
    3.Can you promise that the solution is right? At least,the main ideal
    4.use the puts("") or putchar() or printf and such things?
    5.init the used array or any value?
    6.use error MAX_VALUE?
*/
#include <bits/stdc++.h>
using namespace std;

const int N = 1e5;

int n,m,dis[N+10];
bool vis[N+10];
vector < pair<int,int> > g[N+100];
queue <int> dl;
int a[N+10];

int main(){
    #ifdef LOCAL_DEFINE
        freopen("F:\\c++source\\rush_in.txt", "r", stdin);
    #endif
    ios::sync_with_stdio(0),cin.tie(0);

    while (cin >> n >> m){
        memset(vis,0,sizeof vis);
        for (int i = 1;i <= n;i++) a[i] = (int) 1e9+7;
        for (int i = 1;i <= n;i++) g[i].clear();
        for (int i = 1;i <= m;i++){
            int x,y,z;
            cin >>x>>y>>z;
            g[x].push_back(make_pair(y,z));
            g[y].push_back(make_pair(x,z));
        }

        memset(dis,255,sizeof dis);
        dis[n] = 0;
        dl.push(n);
        while (!dl.empty()){
            int x = dl.front();
            dl.pop();
            for (int i = 0;i < (int)g[x].size();i++){
                int y = g[x][i].first;
                if (dis[y]==-1){
                    dis[y] = dis[x] + 1;
                    dl.push(y);
                }
            }
        }

        vis[1] = true;
        dl.push(1);
        while (!dl.empty()){
            int x = dl.front();
            dl.pop();
            int mi = (int) 1e9 + 10;
            for (int i = 0;i < (int) g[x].size();i++){
                int y = g[x][i].first;
                if (dis[y]==dis[x]-1){
                    mi = min(mi,g[x][i].second);
                }
            }

            a[dis[x]] = min(mi,a[dis[x]]);
            for (int i = 0;i < (int) g[x].size();i++){
                int y = g[x][i].first;
                if (!vis[y] && dis[y]==dis[x]-1 && g[x][i].second==mi){
                    vis[y] = true;
                    dl.push(y);
                }
            }
        }

        cout << dis[1] << endl;
        for (int i = dis[1];i >= 1;i--) {
            cout << a[i];
            if (i==1) cout << endl;else cout << ' ';
        }
    }

    return 0;
}
时间: 2024-10-12 11:32:16

【例题 6-20 UVA - 1599】Ideal Path的相关文章

UVa 1599 Ideal Path【BFS】

题意:给出n个点,m条边,每条边上涂有一个颜色,求从节点1到节点n的最短路径,如果最短路径有多条,要求经过的边上的颜色的字典序最小 紫书的思路:第一次从终点bfs,求出各个节点到终点的最短距离, 第二次bfs从起点沿着每到达一个节点d[]减少1来走,按照颜色的字典序最小的路径来走 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include&

UVA 1599 Ideal Path(双向bfs+字典序+非简单图的最短路+队列判重)

https://vjudge.net/problem/UVA-1599 给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小.一对结点可能有多条边,一条边可能连接相同的结点(自环).输入保证结点1可以到达结点n.颜色是1~10^9的整数. 分析: 从题目中我们可以看出,题目中的无向图是可以出现自环和重边的,自环我们可以在输入的时候检查并排

UVA 1599 Ideal Path(bfs1+bfs2,双向bfs)

给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小.一对结点间可能有多条边,一条边可能连接两个相同结点.输入保证结点1可以达到结点n.颜色为1~10^9的整数. 第一次bfs逆向搜索,得到每个点到终点的最短距离,找出最短路:第二次bfs根据最短距离可以选择满足条件的最短路. 1 #pragma comment(linker, "

UVa 1599 Ideal Path (两次BFS)

题意:给出n个点,m条边的无向图,每条边有一种颜色,求从结点1到结点n颜色字典序最小的最短路径. 析:首先这是一个最短路径问题,应该是BFS,因为要保证是路径最短,还要考虑字典序,感觉挺麻烦的,并不好做,事实用两次BFS, 第一次是倒序BFS,目的是得到从结点 i 到结点n的最短距离,然后再从第一个点开始到最后一个,要保证在查找时,每经过一点要让d值恰好减少1, 直到终点,这也是一个BFS,因为这个字典序在某个结点是一样的,所以是两个BFS,我超时了好几次,因为少写了一个vis, 一定要细心,

UVA 1599 Ideal Path

题意: 给出n和m,n代表有n个城市.接下来m行,分别给出a,b,c.代表a与b之间有一条颜色为c的道路.求最少走几条道路才能从1走到n.输出要走的道路数和颜色.保证颜色的字典序最小. 分析: bfs,先倒搜一次,求出每个点到终点的距离d[i].然后从起点走,每次走到新点保证d-1且颜色最小. 代码: #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #

逆向+两次bfs(UVA 1599)

为什么都说简单好想咧.坦白从宽看了人家的代码,涨了好多姿势,, http://blog.csdn.net/u013382399/article/details/38227917 被一个细节坑了.. 2147483647是0x7fffffff啊啊啊,7个f!!! 1 #include <iostream> 2 #include <sstream> 3 #include <cstdio> 4 #include <cstring> 5 #include <c

UVa1599,Ideal Path

说实话,这题参考的: http://blog.csdn.net/u013382399/article/details/38227917 倒着BFS就把我难住了T T,原来这样倒着BFS一遍,遍历完所有的点后就能得到每一点到终点的最短距离啊(其实做完反思后仔细想了想,发现其实当第一次bfs到首节点时,该图已经遍历完成了),一开始没转过这个弯来T T,我直接调用了N次dfs(i)囧rz.... 一开始我还想着吧color[]排序...这样更费时.....我写的dfs2()写着写着就乱了,本来思路还清

UVa1599 Ideal Path(双向bfs+字典序+非简单图的最短路+队列判重)

题目大意: 对于一个n个房间m条路径的迷宫(Labyrinth)(2<=n<=100000, 1<=m<=200000),每条路径上都涂有颜色,颜色取值范围为1<=c<=10^9.求从节点1到节点n的一条路径,使得经过的边尽量少,在这样的前提下,如果有多条路径边数均为最小,则颜色的字典序最小的路径获胜.一条路径可能连接两个相同的房间,一对房间之间可能有多条路径.输入保证可以从节点1到达节点n. 更多细节可以参考原题:UVa1599 分析: 从题目中我们可以看出,题目中的

Uva 1599 最佳路径

题目链接:https://uva.onlinejudge.org/external/15/1599.pdf 题意: 保证在最短路的时候,输出字典序最小的路径. 方法: 路径上有了权值,可以利用图论的数据结构来BFS,很方便. 逆序BFS,找到每个点距离终点的最短路长 d[x] ; 然后,从起点,沿着 d[u] = d[v] + 1; 的路径,分层BFS,选字典序最小的.找到那个最小字典序的节点之后,从新建队列.直到找完 d[0]; #include <bits/stdc++.h> using