• 清北学堂-图论--二进制拆分--最短路--潜伏


    样例输入:

    3
    5 10 3
    1 3 437
    1 2 282
    1 5 328
    1 2 519
    1 2 990
    2 3 837
    2 4 267
    2 3 502
    3 5 613
    4 5 132
    1 3 4
    10 13 4
    1 6 484
    1 3 342
    2 3 695
    2 3 791
    2 8 974
    3 9 526
    4 9 584
    4 7 550
    5 9 914
    6 7 444
    6 8 779
    6 10 350
    8 8 394
    9 10 3 7
    10 9 4
    1 2 330
    1 3 374
    1 6 194
    2 4 395
    2 5 970
    2 10 117
    3 8 209
    4 9 253
    5 7 864
    8 5 10 6  

    样例输出:

    40
    60
    90
    70
    90
    8
    30
    70
    100
    10
    9
    81
    63
    1
    4

    数据范围:

    思路:

    二进制拆分,对于拆出的每一位,0的放一边,1的放一边,将其中一组作为起点,都扔入队列中,每次跑到另外一组,记录最小的值,不关心是哪两点之间的最小值,对于每一位重复此步骤,一直取最小,最后输出答案。。

    注意数的位数。。。。。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<cmath>
    #define MAXN 1000000
    using namespace std;
    bool v[MAXN],f[MAXN];
    int T,n,m,k,per[MAXN],cnt,vis[MAXN],head[MAXN];
    long long dist[MAXN],ans;
    struct node{int to,nxt,dis;}e[MAXN<<1];
    queue<int> q;
    void add(int from,int to,int dis)
    {
    	e[++cnt].to=to;
    	e[cnt].dis=dis;
    	e[cnt].nxt=head[from];
    	head[from]=cnt;
    }
    void spfa()
    {
    	for(int i = 1 ; i <= n ; i ++) dist[i] =2147483647;
    	for(int i = 1;i <= k;i ++)
    		if(f[i])
    		dist[per[i]] = 0,q.push(per[i]),v[per[i]] = 1;
    	while (!q.empty()){
    		int x = q.front(); 
    		q.pop();
    		v[x] = 0;
    		for(int i = head[x] ; i ; i = e[i].nxt){
    			int y = e[i].to;
    			int z = e[i].dis;
    			if(dist[y] > dist[x] + z){
    				dist[y] = dist[x] + z;
    				if(!v[y])
    				{
    					q.push(y),v[y] = 1;
    				}
    			}
    		}
    	}
    	for(int i = 1;i <= k;i ++)
    		if(!f[i])
    			ans = min(ans,dist[per[i]]);
    }
    int main()
    {
    	#ifdef yilnr
    	#else
    		freopen("hide.in","r",stdin);
    		freopen("hide.out","w",stdout);
    	#endif
    	scanf("%d",&T);
    	while(T--)
    	{
    		ans=2147483647;
    		scanf("%d%d%d",&n,&m,&k);
    		for(int i=1;i<=m;i++)
    		{
    			int a,b,c;
    			scanf("%d%d%d",&a,&b,&c);
    			add(a,b,c);
    			add(b,a,c);
    		}
    		for(int i=1;i<=k;i++)scanf("%d",&per[i]);	
    		for(int j=0;j<=16;j++)
    		{
    			for(int i=1;i<=k;i++)
    			{
    				if((per[i]>>j) & 1) f[i] = 1;
    				else f[i] = 0;
    			}
    			spfa();
    		}
    		if(ans==2147483647)printf("-1
    ");
    		else printf("%lld
    ",ans);
    		memset(head,0,sizeof(head));
    		cnt=0;
    	}
    	fclose(stdin);fclose(stdout);
    	return 0;
    }
    

      

  • 相关阅读:
    改造vant日期选择
    css3元素垂直居中
    npm综合
    (转)网页加水印方法
    Mac下IDEA自带MAVEN插件的全局环境配置
    隐藏注册控件窗口
    High performance optimization and acceleration for randomWalk, deepwalk, node2vec (Python)
    How to add conda env into jupyter notebook installed by pip
    The Power of WordNet and How to Use It in Python
    背单词app测评,2018年
  • 原文地址:https://www.cnblogs.com/yelir/p/11360306.html
Copyright © 2020-2023  润新知