牛客练习赛67 牛妹游历城市 题解(最短路+虚点)

题目链接

题目大意

给你n(n<=1e5)个点,每个点有一个权值a[i],要你求从1到n的最短路

a[i]∩a[j]=0;dis[i][j]=0

a[i]∩a[j]!=0;dis[i][j]=lowbit(a[i]∩a[j])

题目思路

首先吐槽一下\(a[i]<2^{32}\) 这是ll级别的,\(int<2^{31}\)真毒瘤

这个题目利用了建虚点,对32个二进制位建立32个虚点,对于每个a[i],如果该二进制位j为1,那么连边权值为 1 << j。(注意虚点到该点的距离为0)

然后跑一个dij即可

你可能会问那这里跑的不就是所有的a[i]&a[j]的二进制位了嘛,而不是那个lowbit的那个二进制嘛

确实,但是你会发现这个是求最短路,那么最短路跑的必然是那个lowbit的那个二进制位

代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e5+50,inf=0x3f3f3f3f,mod=998244353;
const double eps=1e-10;
int n;
ll a[maxn];//int 2^31-1,要ll
int head[maxn],cnt;
ll dis[maxn];
struct edge{
    int to,next;
    ll w;
}e[maxn<<6];
void add(int u,int v,ll w){
    e[++cnt]={v,head[u],w};
    head[u]=cnt;
}
void init(){
    cnt=0;
    memset(head,0,sizeof(head));
}
void dij(int x){
	priority_queue<pii,vector<pii>,greater<pii> > que;
	memset(dis,0x3f,sizeof(dis));
	dis[x]=0;
	que.push({0,x});
	while(!que.empty()){
		int len=que.top().first;
		int pos=que.top().second;
		que.pop();
		if(len<=dis[pos]){
			for(int i=head[pos];i;i=e[i].next){
				if(dis[e[i].to]>dis[pos]+e[i].w){
					dis[e[i].to]=dis[pos]+e[i].w;
					que.push({dis[e[i].to],e[i].to});//一定注意是len为fi
				}
			}
		}
	}
}
signed main(){
    int _;scanf("%d",&_);
    while(_--){
        scanf("%d",&n);
        init();
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            for(int j=0;j<=31;j++){
                if(a[i]&(1ll<<j)){
                    add(i,n+j+1,(1ll<<j));//n+j+1为虚点
                    add(n+j+1,i,0);
                }
            }
        }
        dij(1);
        if(dis[n]==INF){
            printf("Impossible\n");
        }else{
            printf("%lld\n",dis[n]);
        }
    }
    return 0;
}

不摆烂了,写题
原文地址:https://www.cnblogs.com/hunxuewangzi/p/13738014.html