您的位置:首页 > 其它

ACM: 图论题 poj 3…

2016-05-19 23:25 330 查看
[align=center]Problem H: Ideal Path[/align]
Description
New labyrinth attraction is open
in New Lostland amusement park. The labyrinth consists of n
rooms connected by m passages. Each passage is colored into
some color ci. Visitors of the labyrinth are
dropped from the helicopter to the room number 1 and their goal is
to get to the labyrinth exit located in the room number
n.

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

Andrew is preparing for the contest. He took a helicopter tour
above New Lostland and made a picture of the labyrinth. Your task
is to help him find the ideal path from the room number 1 to the
room 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 that
ai < bi, and
aj = bj for all j
< i.
Input

The first line of the input file
contains integers n and m —the number of rooms and
passages, respectively (2 <= n
<= 100 000, 1 <= m
<= 200 000). The following m lines describe
passages, each passage is described with three integer numbers:
ai, bi, and
ci — the numbers of rooms it connects and its
color (1 <= ai,
bi <= n, 1 <=
ci <= 109). Each
passage can be passed in either direction. Two rooms can be
connected with more than one passage, there can be a passage from a
room to itself. It is guaranteed that it is possible to reach the
room number n from the room number 1.
Output

The first line of the output
file must contain k — the length of the shortest path from
the room number 1 to the room number n. The second line must
contain k numbers — the colors of passages in the order they
must 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
= 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 ] )

   {

    int
v = 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 ] )

   {

    int
v = 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;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: