ACM: 图论题 poj 3…

来源:互联网 发布:win7如何安装linux系统 编辑:程序博客网 时间:2024/05/19 00:13
Problem H: Ideal Path
Description
New labyrinth attraction is openin New Lostland amusement park. The labyrinth consists of nrooms connected by m passages. Each passage is colored intosome color ci. Visitors of the labyrinth aredropped from the helicopter to the room number 1 and their goal isto get to the labyrinth exit located in the room numbern.

Labyrinth owners are planning to run a contest tomorrow. Severalrunners will be dropped to the room number 1. They will run to theroom number n writing down colors of passages as they runthrough them. The contestant with the shortest sequence of colorsis the winner of the contest. If there are several contestants withthe same sequence length, the one with the ideal path is thewinner. The path is the ideal path if its color sequence is thelexicographically smallest among shortest paths.

Andrew is preparing for the contest. He took a helicopter tourabove New Lostland and made a picture of the labyrinth. Your taskis to help him find the ideal path from the room number 1 to theroom number n that would allow him to win the contest.

Note

A sequence (a1, a2, . . . ,ak) is lexicographically smaller than a sequence(b1, b2, . . . ,bk) if there exists i such thatai < bi, andaj = bj for all j< i.

Input

The first line of the input filecontains integers n and m —the number of rooms andpassages, respectively (2 <= n<= 100 000, 1 <= m<= 200 000). The following m lines describepassages, each passage is described with three integer numbers:ai, bi, andci — the numbers of rooms it connects and itscolor (1 <= ai,bi <= n, 1 <=ci <= 109). Eachpassage can be passed in either direction. Two rooms can beconnected with more than one passage, there can be a passage from aroom to itself. It is guaranteed that it is possible to reach theroom number n from the room number 1.

Output

The first line of the outputfile must contain k — the length of the shortest path fromthe room number 1 to the room number n. The second line mustcontain k numbers — the colors of passages in the order theymust be passed in the ideal path.

Sample Input

4 6
1 2 1
1 3 2
3 4 3
2 3 1
2 4 4
3 1 1

Sample Output

2
1 3

 

题意: 一个图, 求出最短路径长度, 并且输出字典序最小的路径. 因为每条路径有一个

     color, 长度都为1.

 

解题思路:

    1. 因为每条路的权值都为1, 最短路径问题. spfa算法改改快速就可以求出.

    2. 设dist[i]表示第i个节点到第n个节点的最短路径. 因此输出最小字典序才是难点.

    问题分析:

       (1). dist[1]: 就是1->n的最短路径. 因为每条边的权值为1, 因此我们把每减小1

            就有一系列的节点, 相当于这条路径的一层(当然路径要连通), 每一层在建

            一个图, 相同dist[i]在同一层. 每一层求出最小的color即可.

        (2).为了保证路径连通性, 选出来的最小值的节点, 要标记.

 

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define MAX 110005
#define MAXSIZE 400005
const int INF = (1<<30);

struct node
{
 int v;
 int color;
 int next;
}edges1[MAXSIZE];

struct pNode
{
 int v;
 int next;
}edges2[MAXSIZE];

int n, m;
int dist[MAX];
int first1[MAXSIZE], first2[MAXSIZE];
int num1, num2;
bool vis[MAX];

inline int min(int a, int b)
{
 return a < b ? a : b;
}

inline void add1(int u, int v, int color)
{
 edges1[num1].v = v;
 edges1[num1].color = color;
 edges1[num1].next = first1[u];
 first1[u] = num1++;
}

inline void add2(int level, int v)
{
 edges2[num2].v = v;
 edges2[num2].next = first2[level];
 first2[level] = num2++;
}

void read_graph()
{
 memset(edges1, -1, sizeof(edges1));
 memset(edges2, -1, sizeof(edges2));
 memset(first1, -1, sizeof(first1));
 memset(first2, -1, sizeof(first2));
 memset(dist, -1, sizeof(dist));
 memset(vis, false, sizeof(vis));
 num1 = num2 = 0;

 int u, v, color;
 for(int i = 1; i <= m; ++i)
 {
  scanf("%d %d %d",&u, &v,&color);
  add1(u, v, color);
  add1(v, u, color);
 }
}

void spfa()
{
 dist[n] = 0;
 queue qu;
 qu.push(n);
 while( !qu.empty() )
 {
  int u = qu.front();
  qu.pop();
  for(int e = first1[u]; e != -1;e = edges1[e].next)
  {
   if( dist[edges1[e].v ] == -1 )
   {
    dist[edges1[e].v ] = dist[u]+1;
    qu.push(edges1[e].v );
   }
  }
 }
}

void printPath()
{
 printf("%d\n", dist[1]);
 int i, e1, e2;
 for(i = 1; i <= n; ++i)
  add2(dist[1]-dist[i], i);
 vis[1] = true;

 int result;
 int temp = 0;
 for(i = 0; i < dist[1]; ++i)
 {
  result = INF;
  for(e2 = first2[i]; e2 != -1;e2 = edges2[e2].next)
  {
   if( vis[edges2[e2].v ] )
   {
    intv = edges2[e2].v;
    for(e1= first1[v]; e1 != -1; e1 = edges1[e1].next)
    {
     if(dist[ edges1[e1].v ] == dist[v]-1 )
     {
      result= min(result, edges1[e1].color);
     }
    }
   }
  }

  if(i != 0) printf(" %d",result);
  else printf("%d",result);
  if(i == dist[1]-1) break;

  for(e2 = first2[i]; e2 !=-1; e2 = edges2[e2].next)
  {
   if( vis[edges2[e2].v ] )
   {
    intv = edges2[e2].v;
    for(e1= first1[v]; e1 != -1; e1 = edges1[e1].next)
    {
     if(dist[ edges1[e1].v ] == dist[v]-1&& result ==edges1[e1].color)
     {
      vis[edges1[e1].v ] = true;
     }
    }
   }
  }
 }
 printf("\n");
}

int main()
{
// freopen("input.txt", "r", stdin);
 while( scanf("%d %d", &n,&m) != EOF )
 {
  read_graph();
  spfa();
  printPath();
 }
 return 0;
}


 

0 0