zoukankan      html  css  js  c++  java
  • UVA

    题意:无向图,边带权,问从1到n最少经过的结点数量,以及在此基础上经过的边权字典序最小的路径。

    以1为源点bfs,每次把边权按从小到大的顺序进行遍历,边权相等的后继结点需要作为一个整体进行后续的bfs,这样能保证每个结点第一次被访问时的路径都是字典序最小的最短路径。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1e5+10,inf=0x3f3f3f3f;
     5 int hd[N],ne,d[N],fa[N],op[N],n,m;
     6 struct E {
     7     int u,v,c,nxt;
     8     bool operator<(const E& b)const {return c<b.c;}
     9 } e[N<<2];
    10 void link(int u,int v,int c) {e[ne]= {u,v,c,hd[u]},hd[u]=ne++;}
    11 queue<int> q;
    12 vector<E> vec;
    13 void upd(int u,int c,int f,int o) {if(d[u]>c)d[u]=c,q.push(u),fa[u]=f,op[u]=o;}
    14 void bfs() {
    15     while(q.size())q.pop();
    16     memset(d,inf,sizeof d);
    17     upd(1,0,0,0),q.push(-1);
    18     while(q.size()) {
    19         vec.clear();
    20         while(1) {
    21             int u=q.front();
    22             q.pop();
    23             if(u==-1)break;
    24             for(int i=hd[u]; ~i; i=e[i].nxt)vec.push_back(e[i]);
    25         }
    26         sort(vec.begin(),vec.end());
    27         for(int i=0,j,k; i<vec.size(); i=j) {
    28             for(j=i+1; j<vec.size()&&vec[j].c==vec[i].c; ++j);
    29             for(int k=i; k<j; ++k) {
    30                 int u=vec[k].u,v=vec[k].v,c=vec[k].c;
    31                 upd(v,d[u]+1,u,c);
    32             }
    33             q.push(-1);
    34         }
    35     }
    36 }
    37 int main() {
    38     while(scanf("%d%d",&n,&m)==2) {
    39         memset(hd,-1,sizeof hd),ne=0;
    40         while(m--) {
    41             int u,v,c;
    42             scanf("%d%d%d",&u,&v,&c);
    43             link(u,v,c);
    44             link(v,u,c);
    45         }
    46         bfs();
    47         vector<int> ans;
    48         for(int u=n; u!=1; u=fa[u])ans.push_back(op[u]);
    49         reverse(ans.begin(),ans.end());
    50         printf("%d
    ",ans.size());
    51         for(int i=0; i<ans.size(); ++i)printf("%d%c",ans[i]," 
    "[i==ans.size()-1]);
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    python——集合
    python——字典
    python——用递归的方法求x的y次幂
    python——全局变量&局部变量
    python——组织列表
    Linux显示网络相关信息
    Linux里的发消息
    Linux中各种压缩文件
    Linux中的man
    Linux的find命令
  • 原文地址:https://www.cnblogs.com/asdfsag/p/12497609.html
Copyright © 2011-2022 走看看