GalaxyOJ-1000 (Shrink point + shortest path)

topic

http://www.gdfzoj.com/oj/contest/247/problems/3
topic
data range

analysis

  • For the first four data, direct brute force mapping and SPFA the shortest path.
  • Analyze, for the following data, it is mainly the "special edge" (that is, the edge obtained from the AND operation) that needs to be squared when building the map. You can optimize this here.
  • It can be considered to update all the points that it can reach through the "special edge" after finishing dis[] of a point.
  • Since the side length is 1, so for each point, the value of the first update must be the smallest. Get the "point weight range" vector and save the point weight as its point number. Every time you discuss it, dfs It can be updated in one step. (You don’t need to change the ones you updated before)

program

#include <cstdio>
#include <cstring>
#include <vector>
#define Add(x,y) (to[++num]=head[x],head[x]=num,V[num]=y)
#define For(x) for(int h=head[x],o=V[h]; h; o=V[h=to[h]])
using namespace std;
int head[200005],to[300005],V[300005],num;
int q[2000000],vis[200005],f[1100000],l,r;
int n,m,val[200005],dis[200005];
vector <int> a[1100000];

void dfs(int x,int ds){     //从某个 权值为 x 的点 通过特殊路到的点,dis=ds 
    if (f[x]) return;
    f[x]=1;
    for (int i=20; i>=0; i--) if (x&(1<<i)) dfs(x^(1<<i),ds);
    if (!a[x].empty()) for (int i=0; i<a[x].size(); i++){
        int o=a[x][i];
        if (vis[o]) continue;
        vis[o]=1;
        dis[o]=ds;
        q[++r]=o;
    }
}

int main(){
    freopen("1.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) scanf("%d",val+i),a[val[i]].push_back(i);
    for (int i=1,x,y; i<=m; i++) scanf("%d%d",&x,&y),Add(x,y);  
    memset(dis,0x7f,sizeof(dis)); dis[1]=0;
    for (q[l=r=0]=vis[1]=1; l<=r; l++){
        int u=q[l];
        For(u) if (!vis[o]){
            vis[o]=1;
            dis[o]=dis[u]+1;
            q[++r]=o;
        }
        dfs(val[u],dis[u]+1);       //讨论一下 u 能连到的特殊路 
    }
    for (int i=1; i<=n; i++)
        printf("%d\n",dis[i]>n?-1:dis[i]);
}

Guess you like

Origin blog.csdn.net/jackypigpig/article/details/78470602