题意:给你一个数n,s,e,n为有多少个车站,s,e是起点和终点,接下来有m条经济路线,再接下来有k条商业线,你最多只能座一条商业线,现在要你求出从s到e的最短路,并输出它所经过的节点还有座商业线的车站。
思路:实际上这道题就是考你对dijkstra的理解了,其中d数组的含意是起点到第i个点的最短距离,那么每次寻找商业路线的时候,是不是可以比较d[e]跟从起点到点u的最小值+从终点到v的最小值+w[u][v]。最后我们可以根据递归输出路径了。
AC代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> using namespace std; #define inf 1e9 const int maxn=100000; int e_cnt; struct Edge { int from,to,dist; }; struct heapnode { int d,u; bool operator < (const heapnode& rhs) const { return d>rhs.d; } }; int n,m; vector<int >g[maxn]; vector<Edge >edge; bool vis[maxn]; int d[maxn]; int p[maxn]; void init() { for(int i=0;i<n;i++)g[i].clear(); edge.clear(); } void addedge(int from,int to,int dist) { edge.push_back((Edge){from,to,dist}); e_cnt=edge.size(); g[from].push_back(e_cnt-1); } void dijkstra(int s) { priority_queue<heapnode>q; for(int i=0;i<n;i++)d[i]=inf; d[s]=0; memset(vis,false,sizeof(vis)); q.push((heapnode){0,s}); while(!q.empty()) { heapnode x=q.top(); q.pop(); int u=x.u; if(vis[u])continue; vis[u]=true; for(int i=0;i<g[u].size();i++) { Edge& e=edge[g[u][i]]; if(d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; p[e.to]=g[u][i]; q.push((heapnode){d[e.to],e.to}); } } } } int S,E; int d1[maxn],d2[maxn]; int p1[maxn],p2[maxn]; void print1(int k) { if(k==S) { printf("%d",k+1); return ; } int t=p1[k]; Edge& e=edge[t]; print1(e.from); printf(" %d",k+1); } void print2(int k) { if(k==E) { printf(" %d",k+1); return; } printf(" %d",k+1); int t=p2[k]; Edge& e=edge[t]; print2(e.from); } int main() { int tot=0; while(~scanf("%d %d %d",&n,&S,&E)) { if(tot)printf("\n"); tot++; S--,E--; init(); scanf("%d",&m); int u,v,w; for(int i=0;i<m;i++) { scanf("%d %d %d",&u,&v,&w); u--,v--; addedge(u,v,w); addedge(v,u,w); } dijkstra(S); for(int i=0;i<n;i++) { d1[i]=d[i]; p1[i]=p[i]; } dijkstra(E); for(int i=0;i<n;i++) { d2[i]=d[i]; p2[i]=p[i]; } int k; scanf("%d",&k); int ans=d1[E]; int oku=-1; int okv=-1; for(int i=0;i<k;i++) { scanf("%d %d %d",&u,&v,&w); u--,v--; if(ans>d1[u]+d2[v]+w) { ans=d1[u]+d2[v]+w; oku=u; okv=v; } if(ans>d1[v]+d2[u]+w) { ans=d1[v]+d2[u]+w; oku=v; okv=u; } } if(oku==-1) { print1(E); printf("\n"); printf("Ticket Not Used\n"); printf("%d\n",ans); } else{ print1(oku); print2(okv); printf("\n"); printf("%d\n",oku+1); printf("%d\n",ans); } } return 0; }
时间: 2024-10-05 12:53:01