4016: 辉夜的夜空明珠

版权声明:神犇使用记得标明出处哦QAQ https://blog.csdn.net/qq_41717018/article/details/83584512

4016 4016 : 辉夜的夜空明珠
时间限制: 1.5 S e c 1.5 Sec 内存限制: 512 M B 512 MB

题目描述
整个回廊可以看作一个 n n 个点 m m 条边的无向图,每条边走动花费的时间为 1 1 。辉夜、永琳、铃仙、因幡帝等 k k 个人或兔子可以通过传送阵分别进入这个图上的k 个特殊的点,然后去寻找闯入者。但是在寻找闯入者之前,他们要聚集到一个点,以增强战斗力。注意,可以先到的人停下不走等后来的人。

闯入者不知道回廊的规则,因此被困住,对辉夜等k 个人的行动没有影响。而辉夜等k个人必须按照回廊的规则走动。

回廊的规则如下:每个点有一个颜色,一共 4 4 种颜色,红、蓝、黄、绿,分别以 R B Y G R、B、Y、G 表示。走动时必须在第 4 p + 1 4p+1 步到 4 p + 4 4p+4 步的时候走四种不同的颜色,当然最后一个不完整的周期内也不能走动相同颜色。注意,起点算第 1 1 步。

现在给定 k k 个起点,辉夜想知道他们最短多长时间能够汇合,若不能汇合输出 1 -1

输入
第一行一个 C a s e Case ,表示测试点编号。

第二行两个数 n n m m ,表示图有 n n 个点 m m 条边。

第三行一个 k k ,表示有 k k 个人。

第四行 k k 个数,表示 k k 个入口的编号。

第五行一个长度为 n n 的字符串,仅包含 R B Y G RBYG ,表示 n n 个点的颜色。

下面 m m 行每行两个数, u i , v i u_{i},v_{i} ,表示第 i i 条边连接了 u i u_{i} v i v_{i}

输出
一个数表示最短汇合时间,不能汇合输出 1 -1

样例输入
1
5 4
4
1 2 3 4
RRRRG
1 5
2 5
3 5
4 5
样例输出
1

提示

数据范围
对于 100 % 100\% 的数据,保证 k 2 , n 50000 , m 200000 , k 10 k\geq2,n≤50000,m≤200000,k≤10

题解:
看到 k k 这么小。。。我就想到可能需要状压 k k 。。。
但事实上不需要。
求出从这 k k 个点出发,到每个点的最短路,并且带着颜色的状态跑。
b f s bfs 即可。
然后算出每个点到这 k k 个出发点的最大值的最小值即可。

#include<bits/stdc++.h>
using namespace std;
#define in inline
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define repd(i,a,b) for(int i=a;i>=b;i--)
#define For(i,a,b) for(int i=a;i<b;i++)
#define _(d) while(d(isdigit(ch=getchar())))
template<class T>in void g(T&t){T x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;t=f*x;}
const int N=5e4+3,M=200004;
struct E{
    int to,nxt;
}e[M<<1];
int head[N],tot,n,m,k,p[N],c[N];
in void ins(int x,int y){
    e[++tot]={y,head[x]};head[x]=tot;
}
typedef pair<int,int>P;
#define mk(a,b) make_pair(a,b)
#define fi first
#define se second
int d[15][17][N];int b[N],pp[N],inf;bool vis[N];
typedef long long ll;
in void spfa(int id,int st){
    queue<P>q;q.push(mk(st,1<<c[st]));
    d[id][1<<c[st]][st]=0;
    while(!q.empty()){
        P now=q.front();q.pop();
        int x=now.fi;//cout<<now.se<<endl;
        for(int i=head[x];i;i=e[i].nxt){
            //cout<<(now.se&(1<<c[e[i].to]))<<endl;
            if(now.se&(1<<c[e[i].to])){
                //puts("orzlkw");
                continue;
            } 
            int S=now.se|(1<<c[e[i].to]);S%=15;
            if(d[id][S][e[i].to]>d[id][now.se][x]+1){
                d[id][S][e[i].to]=d[id][now.se][x]+1;
                q.push(mk(e[i].to,S));
            }
        }
    }
}
char ch[N];
int main(){
    //freopen(".in","r",stdin);freopen(".out","w",stdout);
    g(n),g(n),g(m);
    g(k);rep(i,1,k) g(p[i]),pp[p[i]]=i;
    scanf("%s",ch+1);
    rep(i,1,n){
        if(ch[i]=='R') c[i]=0;
        if(ch[i]=='B') c[i]=1;
        if(ch[i]=='Y') c[i]=2;
        if(ch[i]=='G') c[i]=3;
    }
    memset(d,0x3f,sizeof(d)),inf=d[1][1][1];
    rep(i,1,m){
        int x,y;g(x),g(y);
        ins(x,y);ins(y,x);
    }
    rep(i,1,k) spfa(i,p[i]);
    int ans=inf;
    rep(i,1,n){
        int t1=0;
        rep(j,1,k){
            int tmp=inf;
            rep(l,0,16){
                tmp=min(tmp,d[j][l][i]);
            }
            //cout<<tmp<<endl;
            t1=max(t1,tmp);
            //cout<<t1<<endl;
        }
        ans=min(ans,t1);
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41717018/article/details/83584512