当前位置: 首页 > news >正文

解题报告-P11844 [USACO25FEB] Friendship Editing G

P11844 [USACO25FEB] Friendship Editing G

题目描述

Farmer John 的 \(N\) 头奶牛编号为 \(1\)\(N\)\(2\le N\le 16\))。奶牛之间的朋友关系可以建模为一个有 \(M\)\(0\le M\le N(N-1)/2\))条边的无向图。两头奶牛为朋友当且仅当图中她们之间存在一条边。

在一次操作中,你可以添加或删除图中的一条边。计算确保以下性质成立所需的最小操作次数:如果奶牛 \(a\)\(b\) 是朋友,则对于每头其他奶牛 \(c\)\(a\)\(b\) 中至少之一与 \(c\) 是朋友。

输入格式

输入的第一行包含 \(N\)\(M\)

以下 \(M\) 行,每行包含一对朋友 \(a\)\(b\)\(1\le a<b\le N\))。每对朋友出现至多一次。

输出格式

输出你需要增加或删除的边的数量。

输入输出样例 #1

输入 #1

3 1
1 2

输出 #1

1

输入输出样例 #2

输入 #2

3 2
1 2
2 3

输出 #2

0

输入输出样例 #3

输入 #3

4 4
1 2
1 3
1 4
2 3

输出 #3

1

说明/提示

样例 1 解释:

该网络不符合性质。我们可以添加边 \((2,3)\)\((1,3)\),或删除边 \((1,2)\) 进行修复。

样例 2 解释:

不需要进行任何修改。

  • 测试点 \(4\sim 13\):对于每一个 \(N\in [6, 15]\) 依次有一个测试点。
  • 测试点 \(14\sim 18\)\(N=16\)

解题报告

我艹,牛逼!!!

先给出一个很难发现的性质:每一个符合条件的关系图,这个图的补图是由若干不相交团组成(团是完全图)

下面是一个经典的证明:

如果奶牛 ab 是朋友,则对于每头其他奶牛 cab 中至少之一与 c 是朋友,假设 a,b 不是朋友,就会有两种情况。(cab 外任意一点)

1.  a   b   2.  a   b\ /c           c

考虑建补图:

1.  a---b   2.  a---b\ /c           c

将图扩展可以推出,ab 外任意一个点要么和 ab 都有连接,要么和 ab 都没连接。同理,两个点与同一个点都有连接,那这两个点也有连接。

所以只要有 ab 外的两点 cd 都跟 ab 有连接,cd 之间就也会有连接,这时 abcd 就会形成一个团,所以整个图就是很多团的并集。

所以问题就转换成了求将一个图的补图修改成很多团的并集的最小操作次数

根据数据范围的提示,我们可以尝试状压 DP。

设点集 \(i\) 表示被选择的点,状态数组为 \(dp[i]\) 表示将这些点改成若干团的并的最小操作次数。

显然有以下转移:

\[dp[i]=\min_{j \in i} (dp[j]+cost(j \oplus i)) \]

\(cost(j \oplus i)\)表示的是将点集 \(j \oplus i\) 代表的图改成团的最小代价。这个方程表示从点集 \(i\) 中的一些点改成完全图的最小代价加上剩余点改成若干个团的最小代价。

每个点集 \(i\)\(cost(i)\) 都可以被预处理出来,统计每两个属于点集 \(i\) 的点之间不存在边的个数(连边),再加上每个属于点集 \(i\) 的点和每个不属于点集 \(i\) 的点之间存在的边的个数(删边),就完成了。

预处理部分时间复杂度 \(O(n^2 \times 2^n)\),状压 DP 部分时间复杂度 \(O(3^n)\),代码如下:

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=21;#define ckmax(x,y) ( x=max(x,y) )
#define ckmin(x,y) ( x=min(x,y) )inline int read()
{int f=1,x=0; char ch=getchar();while(!isdigit(ch)) { if(ch=='-') f=-1; ch=getchar(); }while(isdigit(ch))  { x=x*10+ch-'0';    ch=getchar(); }return f*x;
}bool e[N][N];
int n,m;
int g[1<<N];
int dp[1<<N];signed main()
{n=read(),m=read();for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)e[i][j]=1;for(int i=1;i<=m;i++){int u=read(),v=read();e[u][v]=e[v][u]=false;}for(int k=0;k<(1<<n);k++)for(int i=1;i<=n;i++){if( !( k&(1<<i-1) ) ) continue;for(int j=1;j<=n;j++){if(i==j) continue;g[k]+=( k&(1<<j-1) ? (!e[i][j]):e[i][j] );}}for(int i=0;i<(1<<n);i++){dp[i]=g[i];for(int j=i;j;j=(j-1)&i)ckmin(dp[i],dp[i^j]+g[j]);}printf("%d",dp[(1<<n)-1]/2);return 0;
}
http://www.rkmt.cn/news/7022.html

相关文章:

  • 说的道理。
  • 【abc180F】Unbranched - Harvey
  • ROS2之节点
  • 详细介绍:如何在公众号接入海外招聘数据分析智能体
  • 密力根油滴实验实验报告
  • 来点人瑞平我
  • 在Unity2021中使用Profiler的Deep Profile功能时内存超高怎么办? - 指南
  • 【P2051】中国象棋 - Harvey
  • Min-Max 容斥小记
  • 【POJ1737】Connected Graph - Harvey
  • 详细介绍:VirtualBox 免费轻量的全能虚拟机,跨平台系统随心装
  • 实用指南:C++ 类型衰变(Type Decay)
  • 某交互题选讲的补题记录
  • 奶龙抽象语录
  • 详细介绍:javascript文本长度检测与自动截取,用于标题长度检测
  • 解题报告-P11670 [USACO25JAN] Cow Checkups S
  • 解码C语言运算符
  • Sort方法学习(伪代码记录)
  • 完整教程:一篇读懂Pormise!!【前端ES6】
  • P9753 [CSP-S 2023] 消消乐
  • Jenkins CVE-2018-1000600漏洞利用与SSRF攻击分析
  • 详细介绍:Python:OpenCV 教程——从传统视觉到深度学习:YOLOv8 与 OpenCV DNN 模块协同实现工业缺陷检测
  • 深入解析:PYcharm——pyqt音乐播放器
  • 专题:Python实现贝叶斯线性回归与MCMC采样数据可视化分析2实例|附代码数据
  • CF 2127F Hamed and AghaBalaSar
  • “Sequential Thinking MCP Server 和codex等AI工具本身任务拆解功能对比
  • 题解:P2624 [HNOI2008] 明明的烦恼
  • XXL-JOB (1)
  • 记录---Vue3对接UE,通过MQTT完成通讯
  • 单例模式