loj 1271

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26981

思路:题目的意思是求给定的起点到终点的最短路径序列,并且这个序列的字典顺序最小。我们可以先求最短路,然后对那些在最短路上的点进行深度优先搜索。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<queue>
  7 #include<set>
  8 using namespace std;
  9 
 10 const int MAXN=55555;
 11 const int inf=1<<30;
 12 vector<int>g[MAXN],vet,ans;
 13 int n,st,ed;
 14 
 15 int dist[MAXN];
 16 bool mark[MAXN];
 17 
 18 struct Node{
 19     int v,d;
 20     Node(int vv,int dd){
 21         v=vv,d=dd;
 22     }
 23     bool operator < (const Node &p) const {
 24         if(p.d!=d)return p.d<d;
 25         return p.v<v;
 26     }
 27 };
 28 
 29 
 30 void Dijkstra()
 31 {
 32     memset(mark,false,sizeof(mark));
 33     fill(dist,dist+MAXN,inf);
 34     priority_queue<Node>que;
 35     que.push(Node(st,0));
 36     dist[st]=0;
 37     while(!que.empty()){
 38         Node p=que.top();
 39         que.pop();
 40         if(mark[p.v])continue;
 41         mark[p.v]=true;
 42         for(int i=0;i<(int)g[p.v].size();i++){
 43             int v=g[p.v][i];
 44             if(mark[v])continue;
 45             if(dist[p.v]+1<dist[v]){
 46                 dist[v]=dist[p.v]+1;
 47                 que.push(Node(v,dist[v]));
 48             }    
 49         }
 50     }
 51 }
 52 
 53 bool dfs(int u)
 54 {
 55     set<int>st;
 56     if(u==ed)return true;
 57     for(int i=0;i<g[u].size();i++){
 58         int v=g[u][i];
 59         if(dist[u]+1==dist[v])st.insert(v);
 60     }
 61     set<int>::iterator iter;
 62     for(iter=st.begin();iter!=st.end();iter++){
 63         ans.push_back(*iter);
 64         if(dfs(*iter))return true;
 65         ans.pop_back();
 66     }
 67     return false;
 68 }
 69         
 70 
 71 
 72 int main()
 73 {
 74     int _case,t=1;
 75     scanf("%d",&_case);
 76     while(_case--){
 77         scanf("%d",&n);
 78         vet.clear();
 79         ans.clear();
 80         for(int i=1;i<MAXN;i++)g[i].clear();
 81         for(int i=1;i<=n;i++){
 82             int x;
 83             scanf("%d",&x);
 84             vet.push_back(x);
 85         }
 86         st=vet[0],ed=vet[(int)vet.size()-1];
 87         for(int i=0;i<(int)vet.size()-1;i++){
 88             int u=vet[i],v=vet[i+1];
 89             g[u].push_back(v);
 90             g[v].push_back(u);
 91         }
 92         Dijkstra();
 93         printf("Case %d:\n",t++);
 94         ans.push_back(st);
 95         dfs(st);
 96         for(int i=0;i<(int)ans.size()-1;i++){
 97             printf("%d ",ans[i]);
 98         }
 99         printf("%d\n",ed);
100     }
101     return 0;
102 }
103 
104         
View Code

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值