• 题解 DTOJ #4016.辉夜的夜空明珠(moon)


    欢迎访问 My Luogu Space


    【题目大意】

    一张无向图,边的长度都为 (1),每个点被染成了 ("R,B,Y,G") 四种颜色中的一种。

    图的行进规则是:从第一步开始,每四步一周期,每周期的四步必须踩在不同的颜色上面(初始位置算第一步,最后几个不完整的周期也不能踩相同颜色)。

    第现在有 (k) 个人分别处在不同的起点,询问他们能否汇聚在同一点,若能则找出最短距离。


    【题解】

    状压 + bfs

    用二进制数 (0001,0010,0100,1000) 分别代表踩过了什么颜色的点。

    (k) 个点一起跑宽搜,若搜的过程中发现某一个点被 (k) 个人都经过了,那么当前状态走过的距离就是最短距离。没有找到就是不能汇聚。

    必须用状态来对一个点判重,因为不同状态走到同一个点,之后可走的方案是不同的。


    【代码】

    // output format !!
    // long long !!
    #include <bits/stdc++.h>
    const int MAXN = 50000+10;
    struct DATA{
    	int x, id, len, f;
    	void build(int _x, int _id, int _c){
    		this->f = 0, this->x = _x, this->id = _id;
    		this->f = _c, this->len = 0;
    	}
    };
    
    int n, m, k, f1[MAXN][15][20], f2[MAXN][15], cnt[MAXN], c[MAXN], s[15];
    int hed[MAXN], nex[MAXN*100], e[MAXN*100], ct;
    char in[MAXN];
    std::queue<DATA> Q;
    
    int bfs(){
    	while(!Q.empty()){
    		DATA x = Q.front(); Q.pop();
    		for(int i=hed[x.x]; i; i=nex[i]){
    			DATA y = x;
    			if((y.f&c[e[i]])) continue;
    			if(f1[e[i]][y.id][y.f|=c[e[i]]]) continue;
    			if(!f2[e[i]][y.id]) f2[e[i]][y.id] = 1, ++cnt[e[i]];
    			if(cnt[e[i]] == k) return y.len+1;
    			if(y.f == 15) y.f = 0;
    			f1[e[i]][y.id][y.f] = 1;
    			++y.len, y.x = e[i];
    			Q.push(y);
    		}
    	}
    	return -1;
    }
    int main(){
    //	freopen("test.in", "r", stdin);
    //	freopen("test.out", "w", stdout);
    	scanf("%d%d%d%d", &n, &n, &m, &k);
    	for(int i=1; i<=k; ++i) scanf("%d", s+i);
    	scanf("%s", in+1);
    	for(int i=1; i<=n; ++i){
    		if(in[i] == 'R') c[i] = 1;
    		if(in[i] == 'B') c[i] = 2;
    		if(in[i] == 'Y') c[i] = 4;
    		if(in[i] == 'G') c[i] = 8;
    	}
    	for(int i=1; i<=k; ++i){
    		DATA a; a.build(s[i], i, c[s[i]]);
    		cnt[s[i]] = f2[s[i]][i] = 1, Q.push(a);
    	}
    	while(m--){
    		int a, b; scanf("%d%d", &a, &b);
    		e[++ct] = b, nex[ct] = hed[a], hed[a] = ct;
    		e[++ct] = a, nex[ct] = hed[b], hed[b] = ct;
    	}
    	printf("%d", bfs());
    	return 0;
    }
    
  • 相关阅读:
    ThinkPHP安全规范指引
    正则表达式:不能包含某些特殊字符串
    头晕是因为虚 ( ̄^ ̄゜)
    vs code中文扩展包
    table-cell width:1% 深入理解
    C#使用NPOI操作Excel
    C#利用LumenWorks.Framework.IO.Csv读取CSV文件
    发送邮件代码
    .net 集合详解
    EF Code First:数据更新最佳实践
  • 原文地址:https://www.cnblogs.com/bosswnx/p/10988113.html
Copyright © 2020-2023  润新知