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>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 100010;
vector<int>g[maxn];
vector<int>c[maxn];
int step[maxn];
int ans[maxn<<1];
int vis[maxn];
int flag;
void bfs1(int n)
{
    queue<int>q;
    step[n]=0;
    q.push(n);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        int sz=g[u].size();
        for(int v=0;v<sz;v++)
        {
            int vv=g[u][v];
            if(vv==1)
            {
                step[1]=step[u]+1;
                return;
            }
            if(step[vv]==-1)
            {
                step[vv]=step[u]+1;
                q.push(vv);
            }
        }
    }
    return;
}
void bfs2()
{
    memset(vis,0,sizeof(vis));
    queue<int>q;
    q.push(1);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        if(step[u]==0)
            return;
        int sz=g[u].size();
        int ff=0;
        int min_=-1;
        for(int i=0;i<sz;i++)
        {
            int vv=g[u][i];
            if(step[vv]==step[u]-1)
            {
                if(min_==-1)
                    min_=c[u][i];
                else
                    min_=min(min_,c[u][i]);
            }
        }
        int tt=step[1]-step[u];
        if(ans[tt]==0)
            ans[tt]=min_;
        else
            ans[tt]=min(min_,ans[tt]);
        for(int v=0;v<sz;v++)
        {
            int vv=g[u][v];
            if(vis[vv]==0&&step[vv]==step[u]-1&&c[u][v]==min_)
            {
                q.push(vv);
                vis[vv]=1;
            }
        }
    }
    return;
}
int main()
{
    int n,m;
    int a,b,c1;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int i,j;
        for(i=0;i<maxn;i++)
            g[i].clear();
        for(i=0;i<maxn;i++)
            c[i].clear();
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&c1);
            if(a==b)
                continue;
            g[a].push_back(b);
            g[b].push_back(a);
            c[a].push_back(c1);
            c[b].push_back(c1);
        }
        memset(step,-1,sizeof(step));
        memset(ans,0,sizeof(ans));
        step[n]=-1;
        bfs1(n);
        //cout<<step[1]<<endl;
        bfs2();
        printf("%d\n",step[1]);
        for(i=0;i<step[1];i++)
        {
            if(i)
                printf(" ");
            printf("%d",ans[i]);
        }
        printf("\n");
    }
}
时间: 2024-10-21 17:12:25

UVA 1599 Ideal Path的相关文章

UVa 1599 Ideal Path (两次BFS)

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

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, "

UVa1599,Ideal Path

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

逆向+两次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

【例题 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)的做法. 如果出现前一段路不是最小字

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

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

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