-
D - Destination Unknown
- Gym - 100625D
- 题意:n个点m条边,s为起点,给一些终点,每一步只能走最短路问有哪些从起点到终点的最短路经过g,h
- 思路:跑一边起点s的最短路,再分别跑一边以g,h为起点的最短路,然后判断是否存在从s-t[i]经过g,h的最短路
- 不能记录路径来判断是因为可能有多条最短路会把g,h覆盖。
-
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define maxn 52005 bool vis[maxn]; int n,m,t,s,g,head[maxn],pre[maxn],px,minn; int a,b,d,x[maxn],cnt,h,T,dis[5][maxn]; vector<int>ans; struct node { int v,to,d; } edge[maxn*2]; void add(int x,int y,int z) { edge[++cnt].v=y; edge[cnt].d=z; edge[cnt].to=head[x]; head[x]=cnt; } struct edg { int ord,w; bool operator<(const edg&b)const { return w>b.w; } } top; void dij(int s,int ord) { priority_queue<edg>q; q.push(edg{s,0}); dis[ord][s]=0; while(!q.empty()) { top=q.top(); q.pop(); for(int i=head[top.ord]; i!=-1; i=edge[i].to) { int v=edge[i].v; int w=edge[i].d; if(dis[ord][v]>dis[ord][top.ord]+w) { dis[ord][v]=dis[ord][top.ord]+w; q.push(edg{v,dis[ord][v]}); } } } } int main() { scanf("%d",&T); while(T--) { cnt=0; ans.clear(); memset(dis,inf,sizeof(dis)); memset(head,-1,sizeof(head)); scanf("%d%d%d",&n,&m,&t); scanf("%d%d%d",&s,&g,&h); while(m--) { scanf("%d%d%d",&a,&b,&d); add(a,b,d); add(b,a,d); } dij(s,1); dij(h,3); dij(g,2); minn=dis[2][h]; for(int i=0; i<t; i++) { scanf("%d",&x[i]); if(dis[1][x[i]]==dis[2][x[i]]+dis[1][h]+minn) ans.push_back(x[i]); else if(dis[1][x[i]]==dis[3][x[i]]+dis[1][g]+minn) ans.push_back(x[i]); } sort(ans.begin(),ans.end()); int len=ans.size(); for(int i=0; i<len; i++) if(i==len-1)printf("%d\n",ans[i]); else printf("%d ",ans[i]); } return 0; }
D - Destination Unknown Gym - 100625D -最短路
最新推荐文章于 2024-02-29 20:11:01 发布