UVa 1599 Ideal Path

原创 2015年11月18日 19:52:34

给一个n个顶点m条边 的无向图。每条边上都涂有一种颜色。求从结点1 到 结点n 的一条路径, 使得经过的边数尽量少,在此前提下, 经过的边的颜色的序列的字典序最小。


一对节点间可能有多条边,一条边可能连接两个相同结点。输入保证结点1 可以到达结点n。

这里用数组模拟链表来存储边。我们首先一次逆向bfs()构造分层网络。然后正向bfs每一步沿着分层步数递减的方向走,每次走的时候标记上在哪一层上走的哪一个颜色边

。这里绝对是个技巧。因为队列中出来的元素必然是兄弟结点全部出来完之后, 才会弹出这些兄弟结点的第一个作为接下来子树的根节点,所以用层数数组可以记录一层边

的颜色最小值, 即使他有多个堂兄弟。这样是完全可以理解的。

需要说明的一点是 构造分层网络时用到的vis数组,必须初始化为-1,否则存在bug,比如这组:

3 2

1 3 2

2 3 3

答案是:

1

2

才对。

但是a掉之后 即使vis置为0,也过了。


还有就是在找每个兄弟结点和孩子连边中的最小色彩值的时候。不知道为什么我把tmp设为足够大。然后每步更新tmp直至最小,这样提交结果却是wa。很是郁闷。

/*=============================================================================   
#   
#      Author: liangshu - cbam    
#   
#      QQ : 756029571    
#   
#      School : 哈尔滨理工大学    
#   
#      Last modified: 2015-11-18 19:54  
#   
#     Filename: H.cpp   
#   
#     Description:    
#        The people who are crazy enough to think they can change the world, are the ones who do !    
=============================================================================*/   
  
#include<iostream>  
#include<sstream>  
#include<algorithm>  
#include<cstdio>  
#include<string.h>  
#include<cctype>  
#include<string>  
#include<cmath>  
#include<vector>  
#include<stack>  
#include<queue>  
#include<map>  
#include<set>  
using namespace std; 
const int INF=400004;
int inq[INF];
int cnt[INF];
int low[INF];
int head[INF];
int n,m,c;
struct Edge
{
    int next_edge,v,t,val;
} edge[INF];

void bfs1(int p){
    memset(low, -1, sizeof(low));
    low[p] = 0;
    queue<int>q;
    q.push(p);
    while(!q.empty()){
        int u = q.front();
        if(u == 1){
            return ;
        }
        q.pop();
        for(int e = head[u]; e != -1; e = edge[e].next_edge){
            if(low[edge[e].v] == -1 && edge[e].v != n){
                low[edge[e].v] = low[u] + 1;
                q.push(edge[e].v);

            }
        }
    }
}
struct Node
{
    int x;
    Node(int x):x(x){
    }
};
 int ans[INF];
 int vis[INF];
  void bfs(int p){
      memset(ans, 0, sizeof(ans));
      memset(vis, 0, sizeof(vis));
     queue<Node>q;
     q.push(Node(p));
     while(!q.empty()){
        int e = q.front().x;
        int tmp = -1;
        q.pop();
        for(int i = head[e]; i != -1; i = edge[i].next_edge){
            if(low[edge[i].v] == low[e] - 1){
                if(tmp == -1){
                    tmp = edge[i].val;
                }
                else{
                    tmp = min(edge[i].val, tmp);
                }
            }
        }
            int t = low[1] - low[e];
            if(ans[t] == 0){
                ans[t] = tmp;
            }
            else{
                ans[t] = min(tmp, ans[t]);
            }
            for(int i = head[e]; i != -1; i = edge[i].next_edge){
                if(!vis[edge[i].v] && edge[i].val == tmp  && low[edge[i].v] == low[e] - 1){
                    q.push(edge[i].v);
                    vis[edge[i].v] = 1;
                }
            }
       }
  }
int main()
{
    int x,y,z;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        memset(head,-1,sizeof(head));
        for(int i=0; i<m; i++)
        {
            scanf("%d%d%d", &x, &y, &z);
            if(x == y){
                continue;
            }
            edge[i].next_edge=head[x];
            edge[i].v=y;
            edge[i].t=1;
            edge[i].val = z;
            head[x]=i;

            edge[i+m].next_edge=head[y];
            edge[i+m].v=x;
            edge[i+m].t=1;
            edge[i+ m].val = z;
            head[y]=i+m;
        }
        bfs1(n);
        bfs(1);
        printf("%d\n%d", low[1], ans[0]);
        for(int i = 1; i < low[1]; i++)
        printf(" %d", ans[i]);
        printf("\n");
    }
    return 0;
}
/*
4 5
1 2 3
2 3 345
3 4 2
4 2 2
1 3 1
*/


版权声明:强烈建议大家加入(Java)全国各校IT精英! 群号 467123855 里面都是大神各种分享 内推渠道 (我的老豆比IT站被阿里销毁了。。。)

Uva - 1599 - Ideal Path

先倒着BFS,找到每个结点i到重点最短距离d[i],然后直接起点开始BFS,如果有多种走法,选颜色字典序最小的走。 AC代码: #include #include #include #inc...

UVA1599 Ideal Path

UVA1599 Ideal Path问题描述: 给定一个无向联通图G,G中有N个顶点,M条边,每条边的长度为一个单位,并有一个整数表示这条边的颜色,求从1到N的最短路,如果有多个,则找出颜色字典序...

UVa 1599 - Ideal Path(BFS)

给出n个点,m条边的无向图,每条边有一种颜色,求从结点1到结点n颜色字典序最小的最短路径。 例题,书上给了思路,首先反向BFS,记录结点到n最短距离,然后从起点BFS,每次优先选择字典序最小的颜色的路...
  • wcr1996
  • wcr1996
  • 2015年02月08日 15:50
  • 1674

例题6-20 UVa1599 Ideal Path(两次BFS)

题意: 看白书 要点: 因为这次需要找字典序最小的边,所以以前随机打印的方法是不行的,这道题用了一个很巧妙的方法:先从终点倒着BFS,将所有结点到终点的最短步数储存起来,然后直接从起点开始走,再一次B...

UVA 1599 Ideal Path【双向bfs+非简单图的最短路】

Ideal Path  UVA - 1599  思路: 从终点开始倒着bfs一次,得到每个点到终点的距离,然后从起点开始,按照每次距离减1的方法寻找接下来的点的编号。按照颜色...
  • Puyar_
  • Puyar_
  • 2017年07月09日 21:26
  • 80

最短路+字典序最小+输出路径(Ideal Path,UVA 1599)

题目链接: https://vjudge.net/problem/UVA-1599 在满足最短路的条件下,字典序最小,输出最短距离以及路径。 一些思考: 紫书上说可以只用一次BFS来完成...

UVa 1599 Ideal Path

题目 UVa 1599 Ideal Path 题解 WLGQ这个题实在是恶心了一发。一开始我在担心会T,后来发现,,并不会,只是一开始写的拙劣。结构体写了又删删了又写,数组开了又删删...
  • QWsin
  • QWsin
  • 2016年03月25日 22:04
  • 371

ACM篇:UVa 1599 -- Ideal Path

先从终点宽搜,得到每个点到终点的距离,保证最短路。再从起点宽搜,保证字典序最小。...

UVa 1599 - Ideal Path <两次BFS>

两个月前就搞这道题,昨天翻出来直接修改的当时的超时代码,经历了多种错误,最后终于还是AC了。 这道题还是挺好的一道题,需要正反两次BFS,需要加各种防超时的判断。实际上还是考差对问题的理解,什么时候...
  • kun768
  • kun768
  • 2015年02月03日 15:05
  • 933

UVA 1599 Ideal Path 【两次BFS+贪心】 (好题)

题目链接题意迷宫中有n个房间,m条路,每条路上都涂上了颜色(用整数表示),求按走的路径的颜色排列的字典序最小的最短路分析贪心方法求最短路当然简单,每条路的长度都是1,BFS、SPFA、Dijkstra...
  • DrCarl
  • DrCarl
  • 2016年07月24日 22:20
  • 132
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVa 1599 Ideal Path
举报原因:
原因补充:

(最多只允许输入30个字)