题目链接: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