zoukankan      html  css  js  c++  java
  • UVa 1599 (字典序最小的最短路) Ideal Path

    题意:

    给出一个图(图中可能含平行边,可能含环),每条边有一个颜色标号。在从节点1到节点n的最短路的前提下,找到一条字典序最小的路径。

    分析:

    首先从节点n到节点1倒着BFS一次,算出每个节点到节点n个最短距离di

    然后从节点1开始再一次BFS,在寻找下一个节点时,必须满足下一个节点v满足对于当前节点u,有du = dv + 1,这样才能保证在最短路上。

    在这个条件下还要满足v的颜色编号是最小的。因为可能有多个颜色相同的最小编号,所以这些节点都要保留下来。

    图的表示方式:这里如果再用往常的邻接表发现不适用了,所以G[u]中保存的与u邻接的edges中边的编号。

      1 #include <cstdio>
      2 #include <vector>
      3 #include <cstring>
      4 #include <queue>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 const int maxn = 100000 + 10;
      9 const int INF = 1000000000 + 10;
     10 
     11 struct Edge
     12 {
     13     int u, v, c;
     14     Edge(int u=0, int v=0, int c=0):u(u), v(v), c(c) {}
     15 };
     16 
     17 vector<Edge> edges;
     18 vector<int> G[maxn];
     19 
     20 void AddEdge(int u, int v, int c)
     21 {
     22     edges.push_back(Edge(u, v, c));
     23     int index = edges.size() - 1;
     24     G[u].push_back(index);
     25 }
     26 
     27 int n, d[maxn];
     28 bool vis[maxn];
     29 vector<int> ans;
     30 
     31 void rev_bfs()
     32 {
     33     memset(vis, 0, sizeof(vis));
     34     queue<int> q;
     35     q.push(n-1);
     36     vis[n-1] = true;
     37     d[n-1] = 0;
     38 
     39     while(!q.empty())
     40     {
     41         int u = q.front(); q.pop();
     42         for(int i = 0; i < G[u].size(); ++i)
     43         {
     44             int e = G[u][i];
     45             int v = edges[e].v;
     46             if(!vis[v])
     47             {
     48                 vis[v] = true;
     49                 d[v] = d[u] + 1;
     50                 q.push(v);
     51             }
     52         }
     53     }
     54 }
     55 
     56 void bfs()
     57 {
     58     memset(vis, 0, sizeof(vis));
     59     vis[0] = true;
     60     ans.clear();
     61 
     62     vector<int> next;
     63     next.push_back(0);
     64     for(int i = 0; i < d[0]; ++i)
     65     {
     66         int min_color = INF;
     67         for(int j = 0; j < next.size(); ++j)
     68         {
     69             int u = next[j];
     70             for(int k = 0; k < G[u].size(); ++k)
     71             {
     72                 int e = G[u][k];
     73                 int v = edges[e].v;
     74                 if(d[u] == d[v] + 1)
     75                     min_color = min(min_color, edges[e].c);
     76             }
     77         }
     78         ans.push_back(min_color);
     79 
     80         vector<int> next2;
     81         for(int j = 0; j < next.size(); ++j)
     82         {
     83             int u = next[j];
     84             for(int k = 0; k < G[u].size(); ++k)
     85             {
     86                 int e = G[u][k];
     87                 int v = edges[e].v;
     88                 if(!vis[v] && d[u] == d[v] + 1 && edges[e].c == min_color)
     89                 {
     90                     vis[v] = true;
     91                     next2.push_back(v);
     92                 }
     93             }
     94         }
     95         next = next2;
     96     }
     97 
     98     printf("%d
    %d", d[0], ans[0]);
     99     for(int i = 1; i < ans.size(); ++i) printf(" %d", ans[i]);
    100     puts("");
    101 }
    102 
    103 int main()
    104 {
    105     //freopen("in.txt", "r", stdin);
    106     int m, u, v, c;
    107     while(scanf("%d%d", &n, &m) == 2)
    108     {
    109         edges.clear();
    110         for(int i = 0; i < n; ++i) G[i].clear();
    111         while(m--)
    112         {
    113             scanf("%d%d%d", &u, &v, &c);
    114             if(u == v) continue;    //最短路中一定不含环
    115             AddEdge(u-1, v-1, c);
    116             AddEdge(v-1, u-1, c);
    117         }
    118 
    119         rev_bfs();
    120         bfs();
    121     }
    122 
    123     return 0;
    124 }
    代码君
  • 相关阅读:
    day1 生活大爆炸版石头剪刀布
    友谊赛
    再数17
    素数统计
    day1 LGTB玩THD
    day1 LGTB学分块
    day1 LGTB玩扫雷
    组合(1-m中选n个数)
    二分查找法,加递归,之前做了一个没加递归,结果就废了
    以前的一个程序,死循环,骚年,卡爆你的电脑吧
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4267038.html
Copyright © 2011-2022 走看看