zoukankan      html  css  js  c++  java
  • 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)

    【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)

    题面

    BZOJ
    洛谷

    题解

    正着做一遍(dij)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更新答案。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define ll long long
    #define MAX 100100
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    struct Line{int v,next,w;}e[MAX*10];
    int h[MAX],cnt=1;
    inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
    int col[MAX];ll dis1[MAX],dis2[MAX];bool vis[MAX];
    struct Node{int x,fr;ll dis;};
    bool operator<(Node a,Node b){return a.dis>b.dis;}
    priority_queue<Node>Q;
    int n,m,K,a[MAX];ll ans;
    void Dijkstra1()
    {
    	memset(dis1,63,sizeof(dis1));memset(vis,0,sizeof(vis));
    	for(int i=1;i<=K;++i)dis1[a[i]]=0,col[a[i]]=a[i],Q.push((Node){a[i],a[i],0});
    	while(!Q.empty())
    	{
    		Node p=Q.top();Q.pop();int u=p.x;
    		if(vis[u])continue;vis[u]=true;
    		for(int i=h[u];i;i=e[i].next)
    		{
    			int v=e[i].v;if(!(i&1))continue;
    			if(dis1[v]>dis1[u]+e[i].w)
    				col[v]=col[u],dis1[v]=dis1[u]+e[i].w,Q.push((Node){v,col[u],dis1[v]});
    		}
    	}
    }
    void Dijkstra2()
    {
    	memset(dis2,63,sizeof(dis2));memset(vis,0,sizeof(vis));
    	for(int i=1;i<=K;++i)dis2[a[i]]=0,Q.push((Node){a[i],a[i],0});
    	while(!Q.empty())
    	{
    		Node p=Q.top();Q.pop();int u=p.x;
    		if(vis[u])continue;vis[u]=true;
    		for(int i=h[u];i;i=e[i].next)
    		{
    			int v=e[i].v;if(i&1)continue;
    			if(col[v]!=col[u])ans=min(ans,dis2[u]+e[i].w+dis1[v]);
    			if(dis2[v]>dis2[u]+e[i].w)
    				dis2[v]=dis2[u]+e[i].w,Q.push((Node){v,col[u],dis2[v]});
    		}
    	}
    }
    int main()
    {
    	int T=read();
    	while(T--)
    	{
    		n=read();m=read();K=read();
    		for(int i=1,u,v,w;i<=m;++i)	u=read(),v=read(),w=read(),Add(u,v,w),Add(v,u,w);
    		for(int i=1;i<=K;++i)a[i]=read();
    		ans=1e18;Dijkstra1();Dijkstra2();
    		printf("%lld
    ",ans);
    		for(int i=1;i<=n;++i)h[i]=col[i]=0;cnt=1;
    	}
    	return 0;
    }
    
  • 相关阅读:
    数据结构栈的链式存储(c语言描述)
    Glide相关api
    mac安装WireShark2.0新手教程
    android的布局 (如何实现空心圆效果的布局)
    Android如何设置只有边框背景透明的背景呢?
    failed parsing overlays.
    SVN 报错问题
    关于Fragment的点击切换数据滞留问题
    数据结构(严蔚敏版)思维导图
    【LeetCode】23.合并K个排序链表
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10736124.html
Copyright © 2011-2022 走看看