USACO09NOV Lights G(meet in the middle)

2023-11-03 03:20
文章标签 meet middle usaco09nov lights

本文主要是介绍USACO09NOV Lights G(meet in the middle),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

洛谷P2962 [USACO09NOV] Lights G

题目大意

有一个有 n n n个点 m m m条边的无向图,每个点的初始状态为 0 0 0

你可以操作任意一个点,操作结束后该点以及所有与该点相邻的点的状态都会改变,由 0 0 0变成 1 1 1或从 1 1 1变成 0 0 0

你需要求出最少的操作次数,使得在所有操作完成之后所有点的状态都是 1 1 1

1 ≤ n ≤ 35 , 1 ≤ m ≤ 595 1\leq n\leq 35,1\leq m\leq 595 1n35,1m595


题解

前置知识:折半搜索(meet in the middle)

我们可以用 v x v_x vx存储对 x x x进行操作之后会改变的点, v x v_x vx每个二进制位表示每个点的状态,二进制位为 1 1 1表示会改变,为 0 0 0表示不会改变。

我们发现,每个点最多修改一次(修改两次相当于不修改)。那我们枚举每个点是否修改,最后判断这个图是否满足题意,满足的话就更新答案。这样做的书剑复杂度是 O ( 2 n ) O(2^n) O(2n)的。

我们考虑用折半搜索,分别搜索 1 1 1 n / 2 n/2 n/2 n / 2 + 1 n/2+1 n/2+1 n n n的状态,如果两种状态合并后的状态中每个点都为 1 1 1,则当前花费就是到达两种状态的花费之和,用当前花费更新答案即可。

每种状态的最小花费可以用 m a p map map来保存,每次修改和查询的时间复杂度为 O ( log ⁡ 2 n ) O(\log 2^n) O(log2n),也就是 O ( n ) O(n) O(n)

总时间复杂度为 O ( n 2 n / 2 ) O(n2^{n/2}) O(n2n/2)

code

#include<bits/stdc++.h>
using namespace std;
int n,m,ans=10000;
long long all=0,v[45];
map<long long,int>mp;
void dfs(int t,int to,long long s,int now){if(!mp.count(s)) mp[s]=now;else mp[s]=min(mp[s],now);if(mp[s^all]||s==all){ans=min(ans,mp[s^all]+now);}if(t<=to){dfs(t+1,to,s,now);dfs(t+1,to,s^v[t],now+1);}
}
int main()
{scanf("%d%d",&n,&m);for(int i=1,x,y;i<=m;i++){scanf("%d%d",&x,&y);v[x]^=(1ll<<y);v[y]^=(1ll<<x);}for(int i=1;i<=n;i++){v[i]^=(1ll<<i);all^=(1ll<<i);}dfs(1,n/2,0,0);dfs(n/2+1,n,0,0);printf("%d",ans);return 0;
}

这篇关于USACO09NOV Lights G(meet in the middle)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/335223

相关文章

Delete the Middle Node of a Linked List

You are given the head of a linked list. Delete the middle node, and return the head of the modified linked list. The middle node of a linked list of size n is the ⌊n / 2⌋th node from the start using

poj 1222 EXTENDED LIGHTS OUT (高斯消元解异或方程组 开关问题)

近距离观摩今天北京站的比赛,向志愿者学姐要了一份题目,看了看H题; 因为数据被弱化,瞬间就想到了背包; 就先研究下标准解法——异或方程组; 下面为转载文: 题意:有一个5*6的矩阵,每个位置都表示按钮和灯,1表示亮,0表示灭。每当按下一个位置的按钮,它和它周围灯的状态全部翻转,问在这样的一个方阵中按下哪些按钮可以把整个方阵都变成灭的,这时1表示按了,0表示没按。 以下

Repair LED lights

Repair LED lights  修理LED灯,现在基本用灯带,就是小型LED灯串联一起的 1)拆旧灯条,这个旧的是用螺丝拧的产品 电闸关掉。 2)五金店买一个,这种是磁铁吸附的产品 现在好多都是铝线啊。。。 小部件,我没用上

SGU 103. Traffic Lights 带限制最短路

每个点有2中颜色 只有一条路上的两个点颜色一样才能通过这条路 最短路加上等待的时间处理 处理的是参考别人的 唉还是太弱了 #include <cstdio>#include <cstring>#include <vector>#include <queue>#include <algorithm>using namespace std;int s, e;int n, m;in

BZOJ 1787 [Ahoi2008]Meet紧急集合 题解与分析

[Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec   Memory Limit: 162 MB Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 2 4 4 6 6 6 Sa

uva 11605 - Lights inside a 3d Grid(概率)

题目链接:uva 11605 - Lights inside a 3d Grid 题目大意:给定一个三维坐标系大小,每个位置有一个灯,初始状态为关,每次随机选中两个点,以这两点为对角线的长方体内所有灯转变状态。操作K次,问说平均情况下,最后会有多少栈灯亮着。 解题思路:枚举坐标系上的点,计算单个点亮着的概率,然后累加即使整体的期望。对于一个点x,y,z,分别考虑每维坐标系,例如x,选中的

Jitsi meet 退出房间后,用户还在房间内

前言 Jitsi Meet 如果客户端非正常退出会议,会产生用户还在房间内,实际用户已经退出的情况,需要一段时间内,才会在UI离开房间,虽然影响不大,但是也容易导致体验不好。 保活 Jitsi Meet 会和前端做一个保活,分为长轮训和websocket,默认是使用长轮训,我们可以在保活上做一点文章 解决方案 进入服务器进入lua脚本 cd /usr/lib/prosody/modul

笔记-docker基于ubuntu22.04安装Jitsi Meet

背景 利用JitsiMeet打造一个可以在线会议的环境,根据躺的坑,做个记录 参考 JitsMeet部署安装说明 开始操作 环境 docker run -it --name ubuntu22.04 ubuntu:22.04 /bin/bash 问题 1、安装 openjdk-11 apt install openjdk-11-jdk 配置环境变量,发现无vi apt i

Internet of Lights and Switches(MAP记录+二分) 2015年湖南省赛第 I 题

题目描述 You are a fan of "Internet of Things"(IoT, 物联网), so you build a nice Internet of Lights and Switches in your huge mansion. Formally, there are n lights and m switches, each switch controls one

POJ 1222 EXTENDED LIGHTS OUT

高斯消元 题意: 给你一个5*6的矩阵,每个点上都有一个灯,按下f[i][j]的按钮,f[i][j]位置的灯的状态会改变,它上下左右的灯的状态也会改变(开变关,关变开)。 现在给出这个矩阵的初始状态,输出按下哪些按钮,使所有的灯都关闭。 分析: 每个位置可以形成增广矩阵的一行,每行有30个系数分别代表0 -29号灯,将可以影响该位置变换的位置(自己,上,下,左,右)置1,其余的置0;这样就形成了