zoukankan      html  css  js  c++  java
  • UVa 1599 理想路径(反向BFS 求最短路径 )

    题意:

    给定一个有重边有自环的无向图,n个点(2 <= n <= 100000), m条边(1 <= m <= 200000), 每条边有一个权值, 求从第一个点到n的最少步数, 如果最少步数相同有多条路径, 那么输出权值字典序最小的一条。

    分析:

    用BFS解决最短路问题, 可以先从终点BFS, 求出每个点到终点的最短距离。 那么最少步数就是起点的最短距离, 最短路径就是从起点每次向最短距离比自己少1的顶点移动(如果有多个则可以随便走), 这样就可以保证走的是最短路径, 如果一开始我们是从起点BFS, 那么这样则不能保证走的是通往终点的最短路径。然后我们就可以从起点出发, 循环最短距离次, 每次选择字典序最少的走,  如果有多个字典序相同则选择多个, 直到走完最短距离, 就可以得出答案。 注意两次BFS都需要添加标记, 不然重边很可能就会导致TLE。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxm = 1e7;
      4 const int maxn = 1e6 + 7;
      5 const int inf = 1e9;
      6 struct Node{
      7     int v,col,next;
      8     Node():v(0),col(0),next(0){}
      9 };
     10 struct ele{
     11     int v;
     12     int dist;
     13     ele(int v, int dist):v(v),dist(dist){}
     14 };
     15 
     16 Node edge[maxn];
     17 int G[maxn], d[maxn];
     18 bool vis[maxn];
     19 int n, m, cnt;
     20 
     21 void build(){
     22     memset(G,-1,sizeof(G));
     23         cnt = 0;
     24         for(int i = 0; i < m; i++){
     25             int u, v, col;
     26             scanf("%d %d %d", &u, &v, &col);
     27             if(u == v) continue;
     28             edge[cnt].v = v;
     29             edge[cnt].col = col;
     30             edge[cnt].next = G[u];
     31             G[u] = cnt++;
     32             edge[cnt].v = u;
     33             edge[cnt].col = col;
     34             edge[cnt].next = G[v];
     35             G[v] = cnt++;
     36         }
     37 }
     38 
     39 void revbfs(){
     40     fill(d,d+maxn, inf);
     41     memset(vis,0,sizeof(vis));
     42     queue<ele> q;
     43     q.push(ele(n,0));
     44     d[n] = 0;
     45     vis[n] = 1;
     46     while(!q.empty()){
     47         ele u = q.front(); q.pop();
     48         d[u.v] = u.dist;
     49         for(int i = G[u.v]; i != -1; i = edge[i].next){
     50             int v = edge[i].v;
     51             if(d[v] < u.dist + 1 || vis[v]){
     52                 continue;
     53             }
     54             q.push(ele(v,u.dist+1));
     55             vis[v] = 1;
     56         }
     57     }
     58 }
     59 void bfs(){
     60     vector<int> path;
     61         memset(vis,0,sizeof(vis));
     62         vis[1] = 1;
     63         vector<int> next;
     64         next.push_back(1);
     65         for(int i = 0; i < d[1]; i++){//the essential minimum step
     66             int min_col = inf;
     67             for(int j = 0; j < next.size(); j++){
     68                 int u = next[j];
     69                 for(int k = G[u]; k != -1; k = edge[k].next){
     70                     int v = edge[k].v;
     71                     if(d[u] == d[v] + 1)
     72                         min_col = min(min_col,edge[k].col);
     73                 }
     74             }
     75             //find out the minimum color
     76             path.push_back(min_col);
     77 
     78             vector<int> next2;
     79             for(int j = 0; j < next.size(); j++){
     80                 int u = next[j];
     81                 for(int k = G[u]; k != -1; k= edge[k].next){
     82                     int v = edge[k].v;
     83                     if(d[u] == d[v] + 1 && !vis[v] && edge[k].col == min_col){
     84                         vis[v] = 1;
     85                         next2.push_back(v);
     86                     }
     87                 }
     88             }
     89             next = next2;
     90         }
     91 
     92 
     93         printf("%d
    %d",(int)path.size(),path[0]);
     94         for(int i = 1; i < path.size(); i++){
     95             printf(" %d",path[i]);
     96         }
     97         puts("");
     98 }
     99 int main(){
    100     freopen("1.txt","r",stdin);
    101     while(~scanf("%d %d", &n, &m)){
    102         build();
    103         revbfs();//反向bfs求出终点到每个点的最短距离
    104         bfs();
    105     }
    106      printf("%.3f",(double)clock()/CLOCKS_PER_SEC);
    107     return 0;
    108 }
  • 相关阅读:
    Subsets II
    Pow(x, n)
    基本数据结构 —— 二叉搜索树(C++实现)
    基本数据结构 —— 堆以及堆排序(C++实现)
    Symmetric Tree
    Same Tree
    C++中三种传递参数方法的效率分析
    Word Search
    Subsets
    Combinations
  • 原文地址:https://www.cnblogs.com/Jadon97/p/7228212.html
Copyright © 2011-2022 走看看