: 辉夜的夜空明珠
时间限制:
内存限制:
题目描述
整个回廊可以看作一个
个点
条边的无向图,每条边走动花费的时间为
。辉夜、永琳、铃仙、因幡帝等
个人或兔子可以通过传送阵分别进入这个图上的k 个特殊的点,然后去寻找闯入者。但是在寻找闯入者之前,他们要聚集到一个点,以增强战斗力。注意,可以先到的人停下不走等后来的人。
闯入者不知道回廊的规则,因此被困住,对辉夜等k 个人的行动没有影响。而辉夜等k个人必须按照回廊的规则走动。
回廊的规则如下:每个点有一个颜色,一共 种颜色,红、蓝、黄、绿,分别以 表示。走动时必须在第 步到 步的时候走四种不同的颜色,当然最后一个不完整的周期内也不能走动相同颜色。注意,起点算第 步。
现在给定 个起点,辉夜想知道他们最短多长时间能够汇合,若不能汇合输出 。
输入
第一行一个
,表示测试点编号。
第二行两个数 和 ,表示图有 个点 条边。
第三行一个 ,表示有 个人。
第四行 个数,表示 个入口的编号。
第五行一个长度为 的字符串,仅包含 ,表示 个点的颜色。
下面 行每行两个数, ,表示第 条边连接了 和 。
输出
一个数表示最短汇合时间,不能汇合输出
。
样例输入
1
5 4
4
1 2 3 4
RRRRG
1 5
2 5
3 5
4 5
样例输出
1
提示
数据范围
对于
的数据,保证
。
题解:
看到
这么小。。。我就想到可能需要状压
。。。
但事实上不需要。
求出从这
个点出发,到每个点的最短路,并且带着颜色的状态跑。
即可。
然后算出每个点到这
个出发点的最大值的最小值即可。
#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;
}