#BFS,二进制#CF1776J Italian Data Centers

洛谷题面
CF1776J


分析

将原图的点所拆开的点按二进制编号,那么同一个点之间连边当且仅当恰好一个二进制位不同,

不同点之间连边颜色相同则其二进制相同,否则完全相反。

可以钦定起点就是 (x,0) 那么需要记录经过了多少次因颜色不同而二进制取反的边,

因为同一个点到达其它二进制完全可以放到最后完成,那么设 dis[y][0/1] 表示从点 x 出发到达点 y 经过偶/奇条边的最短距离

那么最后枚举终点二进制位 1 的个数,可以取反奇数次将 1 删除,或者取反偶数次将 1 补齐,这样时间复杂度为 O(nm+n2k)


代码

#include <cstdio>
#include <cctype>
#include <queue>
using namespace std;
const int N=111; struct node{int y,next;}e[N*N];
int dis[N][2],ans,n,m,k,a[N],as[N],et=1; queue<int>q;
int iut(){
	int ans=0; char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=ans*10+c-48,c=getchar();
	return ans;
}
void bfs(int st){
	for (int i=1;i<=n;++i) dis[i][0]=dis[i][1]=0x3f3f3f3f;
	dis[st][0]=0,q.push(st<<1);
	while (!q.empty()){
		int x=q.front()>>1,z=q.front()&1; q.pop();
		for (int i=as[x];i;i=e[i].next){
			int Z=z^(a[x]!=a[e[i].y]);
			if (dis[e[i].y][Z]>dis[x][z]+1){
				dis[e[i].y][Z]=dis[x][z]+1;
				q.push(e[i].y<<1|Z);
			}
		}
	}
}
int main(){
	n=iut(),m=iut(),k=iut();
	for (int i=1;i<=n;++i) a[i]=iut();
	for (int i=1;i<=m;++i){
		int x=iut(),y=iut();
		e[++et]=(node){y,as[x]},as[x]=et;
		e[++et]=(node){x,as[y]},as[y]=et;
	}
	for (int i=1;i<=n;++i){
		bfs(i);
		for (int x=1;x<=n;++x)
		for (int j=0;j<=k;++j)
		    ans=max(ans,min(dis[x][0]+j,dis[x][1]+k-j));
	}
	return !printf("%d",ans);
}
posted @   lemondinosaur  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2020-10-25 #莫比乌斯反演#ZOJ 3435 Ideal Puzzle Bobble SP7001 VLATTICE
点击右上角即可分享
微信分享提示