[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\n");
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?'\n':'-');
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\n");
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() {;}
代码

 

posted @ 2017-08-22 18:25  拿叉插猹哈  阅读(447)  评论(0编辑  收藏  举报