UVa 1599 Ideal Path

给一个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  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
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;
    queueq;
    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));
     queueq;
     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


你可能感兴趣的:(dfs,bfs,搜索)