loj 1271

时间:2023-03-09 15:43:29
loj 1271

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

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

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
using namespace std; const int MAXN=;
const int inf=<<;
vector<int>g[MAXN],vet,ans;
int n,st,ed; int dist[MAXN];
bool mark[MAXN]; struct Node{
int v,d;
Node(int vv,int dd){
v=vv,d=dd;
}
bool operator < (const Node &p) const {
if(p.d!=d)return p.d<d;
return p.v<v;
}
}; void Dijkstra()
{
memset(mark,false,sizeof(mark));
fill(dist,dist+MAXN,inf);
priority_queue<Node>que;
que.push(Node(st,));
dist[st]=;
while(!que.empty()){
Node p=que.top();
que.pop();
if(mark[p.v])continue;
mark[p.v]=true;
for(int i=;i<(int)g[p.v].size();i++){
int v=g[p.v][i];
if(mark[v])continue;
if(dist[p.v]+<dist[v]){
dist[v]=dist[p.v]+;
que.push(Node(v,dist[v]));
}
}
}
} bool dfs(int u)
{
set<int>st;
if(u==ed)return true;
for(int i=;i<g[u].size();i++){
int v=g[u][i];
if(dist[u]+==dist[v])st.insert(v);
}
set<int>::iterator iter;
for(iter=st.begin();iter!=st.end();iter++){
ans.push_back(*iter);
if(dfs(*iter))return true;
ans.pop_back();
}
return false;
} int main()
{
int _case,t=;
scanf("%d",&_case);
while(_case--){
scanf("%d",&n);
vet.clear();
ans.clear();
for(int i=;i<MAXN;i++)g[i].clear();
for(int i=;i<=n;i++){
int x;
scanf("%d",&x);
vet.push_back(x);
}
st=vet[],ed=vet[(int)vet.size()-];
for(int i=;i<(int)vet.size()-;i++){
int u=vet[i],v=vet[i+];
g[u].push_back(v);
g[v].push_back(u);
}
Dijkstra();
printf("Case %d:\n",t++);
ans.push_back(st);
dfs(st);
for(int i=;i<(int)ans.size()-;i++){
printf("%d ",ans[i]);
}
printf("%d\n",ed);
}
return ;
}