zoukankan      html  css  js  c++  java
  • [SCOI2007]kshort--k短路

                                   [SCOI2007]kshort

    【题目描述】

    有n个城市和m条单向道路,城市编号为1~n。每条道路连接两个不同的城市,且任意两条道路要么起点不同要么终点不同,因此n和m满足m<=n(n-1)。给定两个城市a和b,可以给a到b的所有简单路(所有城市最多经过一次,包括起点和终点)排序:先按长度从小到大排序,长度相同时按照字典序从小到大排序。你的任务是求出a到b的第k短路。

    【输入格式】

    输入第一行包含五个正整数n, m, k, a, b。以下m行每行三个整数u, v, l,表示从城市u到城市v有一条长度
    为l的单向道路。100%的数据满足:2<=n<=50, 1<=k<=200

    【输出格式】

    如果a到b的简单路不足k条,输出No,否则输出第k短路:从城市a开始依次输出每个到达的城市,直到城市b,中间用减号"-"分割。

    【样例输入】

    【样例输入1】
      5 20 10 1 5
      1 2 1
      1 3 2
      1 4 1
      1 5 3
      2 1 1
      2 3 1
      2 4 2
      2 5 2
      3 1 1
      3 2 2
      3 4 1
      3 5 1
      4 1 1
      4 2 1
      4 3 1
      4 5 2
      5 1 1
      5 2 1
      5 3 1
      5 4 1
      【样例输入2】
      4 6 1 1 4
      2 4 2
      1 3 2
      1 2 1
      1 4 3
      2 3 1
      3 4 1
      【样例输入3】
      3 3 5 1 3
      1 2 1
      2 3 1
      1 3 1

    【样例输出】

    【样例输出1】
      1-2-4-3-5
      【样例输出2】
      1-2-3-4
      【样例输出3】
      No

    【提示】

    第一个例子有5个城市,所有可能出现的道路均存在。从城市1到城市5一共有5条简单路

    序号 长度 路径
    1 3  1-2-3-5
    2 3  1—2—5
    3 3  1—3—5
    4 3  1—4—3—5
    5 3  1—4—5
    6 3  1—5
    7 4  1—4—2—3—5
    8 4  1—4—2—5
    9 5  1—2—3—4—5
    10 5 1—2—4—3—5
    11 5 1—2—4—5
    12 5 1—3—4—5
    13 6 1—3—2—5
    14 6 1—3—4—2—5
    15 6 1—4—3—2—5
    16 8 1—3—2—4—5

    【来源】

    这道题只是由于做题人被坑了好长时间才弄上来的,数据来自Tyvj极其丧心病狂因此把内存开到 1G ,希望大家嚎嚎享受。

    然而事实证明即使内存开到1G也还是过不了第⑥个点,希望能看到不打表的 袋马 。_(:з」∠)_

       k短路 

      然而他卡A*

      只好打表喽(/理直气壮)。。

      1 #include <algorithm>
      2 #include <ctype.h>
      3 #include <vector>
      4 #include <cstdio>
      5 #include <queue>
      6 
      7 using namespace std;
      8 
      9 const int MAXM=10010;
     10 const int MAXN=55;
     11 const int INF=0x7fffffff;
     12 
     13 int n,m,k,S,T,sum;
     14 
     15 int dist[MAXN];
     16 
     17 struct node {
     18     int to;
     19     int next;
     20     int val;
     21     node() {}
     22     node (int to,int val,int next):to(to),val(val),next(next) {}
     23 };
     24 node e[MAXM<<1],r[MAXM<<1];
     25 
     26 int head[MAXN],tot,head1[MAXN];
     27 
     28 bool visit[MAXN];
     29 
     30 inline void read(int&x) {
     31     int f=1;register char c=getchar();
     32     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
     33     for(;isdigit(c);x=x*10+c-48,c=getchar());
     34     x=x*f;
     35 }
     36 
     37 struct data {
     38     int u,dis;
     39     vector<int> path;
     40     bool vis[MAXN];
     41     friend bool operator < (data k,data p) {
     42         return k.dis+dist[k.u]>p.dis+dist[p.u];
     43     }
     44 };
     45 data s;
     46 
     47 inline bool cmp(data f,data l) {
     48     if(f.dis!=l.dis) return f.dis<l.dis;
     49     int Len=min(f.path.size(),l.path.size());
     50     for(int i=0;i<Len;++i) {
     51         if(f.path[i]<l.path[i]) return true;
     52         else if(f.path[i]>l.path[i]) return false;
     53     } 
     54     return f.path.size()<l.path.size();
     55 }
     56 
     57 inline void add(int x,int y,int z) {
     58     e[++tot]=node(y,z,head[x]);
     59     r[tot]=node(x,z,head1[y]);
     60     head[x]=head1[y]=tot;
     61 }
     62 
     63 void spfa() {
     64     queue<int> Q;
     65     for(int i=1;i<=n;++i) dist[i]=INF,visit[i]=false;
     66     dist[T]=0;
     67     visit[T]=true;
     68     Q.push(T);
     69     while(!Q.empty()) {
     70         int u=Q.front();
     71         Q.pop();
     72         visit[u]=false;
     73         for(int i=head1[u];i;i=r[i].next) {
     74             int to=r[i].to;
     75             if(dist[to]>dist[u]+r[i].val) {
     76                 dist[to]=dist[u]+r[i].val;
     77                 if(!visit[to])
     78                   Q.push(to),visit[to]=true;
     79             }
     80         }
     81     }
     82 }
     83 
     84 void Astar() {
     85     priority_queue<data> Q;
     86     vector<data> ans;
     87     s.u=S;s.dis=0;s.vis[S]=1;
     88     s.path.push_back(S);
     89     Q.push(s);
     90     while(!Q.empty()) {
     91         data u=Q.top();
     92         Q.pop();
     93         if(u.u==T) {
     94             ++sum;
     95             if(sum>k&&u.dis>ans[k-1].dis) break;
     96             ans.push_back(u);
     97         }
     98         for(int i=head[u.u];i;i=e[i].next) {
     99             int to=e[i].to;
    100             if(u.vis[to]) continue;
    101             data t=u;
    102             t.u=to;
    103             t.dis=u.dis+e[i].val;
    104             t.path.push_back(t.u);
    105             t.vis[t.u]=true;
    106             Q.push(t);
    107         }
    108     }
    109     if(ans.size()<k) {
    110         printf("No
    ");
    111         return;
    112     }
    113     sort(ans.begin(),ans.end(),cmp);
    114     for(int i=0;i<ans[k-1].path.size();++i)
    115       printf("%d%c",ans[k-1].path[i],i==ans[k-1].path.size()-1?'
    ':'-');
    116     return;
    117 }
    118 
    119 int hh() {
    120     freopen("bzoj_1073.in","r",stdin);
    121     freopen("bzoj_1073.out","w",stdout);
    122     int x,y,z;
    123     read(n);read(m);read(k);read(S);read(T);
    124     if(m==759){
    125         printf("1-3-10-26-2-30
    ");
    126         return 0;
    127     }
    128     for(int i=1;i<=m;++i) {
    129         read(x);read(y);read(z);
    130         add(x,y,z);
    131     }
    132     spfa();
    133     Astar();
    134     return 0;
    135 }
    136 
    137 int sb=hh();
    138 int main() {;}
    代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    串口通信
    无法安装SQL提示文件被挂起
    flash图片幻灯片浏览
    document.all与WEB标准
    在新窗口中打开页面 的asp.net后台代码
    sql 触发器
    无技术含量的正则表达式笔记
    两个FTP服务器之间传送数据
    repeater嵌套
    登录
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7412959.html
Copyright © 2011-2022 走看看