您的位置:首页 > 大数据 > 人工智能

UVA 11374(p329)----Airport Express

2016-03-07 11:38 411 查看
#include<bits/stdc++.h>
#define debu
using namespace std;
const int INF=999999;
const int maxn=1e4+50;
struct Edge
{
int from,to,dist;
Edge(int a=0,int b=0,int c=0):from(a),to(b),dist(c) {}
};
struct HeapNode
{
int d,u;
bool operator < (const HeapNode& rhs) const
{
return d>rhs.d;
}
HeapNode(int a,int b):d(a),u(b) {}
};
struct Dijkstra
{
int n,m;
int p[maxn];
vector<Edge> edges;
vector<int> G[maxn];
bool done[maxn];
void init(int n)
{
this->n=n;
for(int i=0; i<n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int dist)
{
edges.push_back(Edge(from,to,dist));
m=edges.size();
G[from].push_back(m-1);
}
void dijkstra(int s,int* d,int* p)
{
priority_queue<HeapNode> q;
for(int i=0; i<n; i++) d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
q.push(HeapNode(0,s));
while(!q.empty())
{
HeapNode x=q.top();
q.pop();
int u=x.u;
if(done[u]) continue;
done[u]=true;
for(int i=0; i<G[u].size(); i++)
{
Edge& e=edges[G[u][i]];
if(d[e.to]>d[u]+e.dist)
{
d[e.to]=d[u]+e.dist;
p[e.to]=e.from;
q.push(HeapNode(d[e.to],e.to));
}
}
}
}
};
int cas=0;
int answer;
int n,s,t,m,k;
Dijkstra ans;
int pos1,pos2;
int num1,num2;
vector<int> step;
vector<Edge> fast;
int p1[maxn],p2[maxn];
int d1[maxn],d2[maxn];
void solve()
{
int ans=d1[t];
// cout<<ans<<" ans"<<endl;
pos1=-1;pos2=-1;
for(int i=0; i<fast.size(); i++)
{
int x=fast[i].from;
int y=fast[i].to;
int z=fast[i].dist;
// cout<<"flag "<<x<<" "<<y<<" "<<z<<endl;
if(ans>d1[x]+z+d2[y])
{
ans=d1[x]+z+d2[y];
pos1=x;
pos2=y;
}
if(ans>d1[y]+z+d2[x])
{
ans=d1[y]+z+d2[x];
pos1=y;
pos2=x;
}
}
//cout<<pos1<<" "<<pos2<<endl;
answer=ans;
}
int way(int pos,int*p)
{
while(pos!=-1)
{
step.push_back(pos+1);
pos=p[pos];
}
return step.size();
}
void output()
{
for(int i=num1-1;i>=0;i--)
printf("%d ",step[i]);
for(int i=num1;i<num2-1;i++)
printf("%d ",step[i]);
printf("%d\n",step[num2-1]);
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif // debug
while(scanf("%d%d%d",&n,&s,&t)!=EOF)
{
cas++;
if(cas!=1) printf("\n");
s--;t--;
fast.clear();
step.clear();
ans.init(n);
scanf("%d",&m);
memset(p1,-1,sizeof(p1));
memset(p2,-1,sizeof(p2));
for(int i=0; i<m; i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
x--;y--;
ans.AddEdge(x,y,w);
ans.AddEdge(y,x,w);
}
scanf("%d",&k);
for(int i=0; i<k; i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
x--;y--;
fast.push_back(Edge(x,y,w));
fast.push_back(Edge(y,x,w));
}
ans.dijkstra(s,d1,p1);
ans.dijkstra(t,d2,p2);
solve();
if(pos1!=-1)
{
num1=way(pos1,p1);
num2=way(pos2,p2);
output();
printf("%d\n",pos1+1);
printf("%d\n",answer);
}
else
{
num1=way(t,p1);
for(int i=num1-1;i>0;i--)
printf("%d ",step[i]);
printf("%d\n",step[0]);
printf("Ticket Not Used\n");
printf("%d\n",answer);
}
}
return 0;
}

题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2369

题解:将路线分成三部分:s到a,a到b(a-b即为坐商业线),b到t。运行两次Dijkstra,求出s到每个点的最短距离d1和t到每个点的最短距离d2,枚举每条商业线a-b 则ans=min{d1[a]+w+d2[b],ans}(a,b可互换(无向边))ans初值为直接从s到t的最短路(也即不经过任何商业线的路径)。注意路径输出:由终点不断推向起点(挂了好几次)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: