The 8th Hebei Collegiate Programming Contest: F - 3 Split

news/2024/9/20 0:11:04

给定n个点的竞赛图,给出一个方案把n个点分为A,B,C三个非空集合,使得所有的边要么连接着相同集合的点,要么从A指向B,要么从B指向C,要么从C指向A。

考虑钦定点 1 属于 B 集合,考察 1 的所有边。以 1 为起点的边,其终点必然属于 B 或 C 中的一个;同理,以 1 为终点的边,其起点必然属于 B 或 A 中的一个。并且,竞赛图保证了所有点都与 1 有边,即上述讨论可以覆盖到所有点。那么除 1 外的每个点都有两种选择,可以转化为 2-SAT 问题求解,简单分析可以知道每一条与 1 无关的边都可以转换为 2-SAT 上的一个限制。时间为 \(O(n^2)\)

换个思路,其实竞赛图+非空集合这两个限制叠加在一起是非常紧的。我们可以通过考察三个点的两两关系证明如果存在方案,那么方案在轮换等价的意义上是唯一的。

依然考虑钦定 1 属于 B,并假设存在一个合法方案。想要构造一个新方案,不失一般性,假设至少有一个原本属于 C 的点变得不再属于 C。任意选取集合 A 中的一个点 a,集合 C 中的一个点 c,则一定有 \(a\to 1\)\(1\to c\)\(c\to a\)。如果 c 在新方案中不再属于 C,因为有 \(1\to c\),那么它只能属于 B,由于存在 \(c\to a\),那么 a 也必须改为属于 B。由于 a 的任意性,原 A 集合内的所有点都必须改为 B。类似的,现在 a 被改为了 B,那么集合 C 中的所有点也必须改为 B。也就是说,要想这个新方案合法,原 B 集合必须有一些点改为 A 和 C,但这也是不可能的。因为现在 a 和 c 都属于了 B,如果有另一个属于 B 的 b(要求 |B|>1) 变成了属于 A,则不符合 \(a\to b\),同理这个 b 也不能属于 C。综上,要构造一个新方案,至少有一个原本属于 A 或 C 的点会变为属于 B,进一步会推出 A 和 C 集合必须为空,故不存在合法新方案。

于是可以钦定 \(1\in B\),枚举 \(x\in A\)\(y\in C\) 满足是一个三元环,然后将剩下的点一个个加入进去。如果存在一个合法方案且这个方案中 \(1\in B\)\(x\in A\)\(y\in C\),那么其所有顶点包含 1,x 和 y 的子图也都存在合法方案且唯一,所以每次加入也最多有一种合法方式,一旦无法放入,说明最终的合法方案中 \((x,1,y)\) 不是分属于 A B C,而是同属于 B。那么就换一对 \((x,y)\) 重复上述步骤。这样做复杂度是 \(O(n^4)\)

为了找到正确的三元组 \((x,1,y)\),在没有合法方案的最坏情况下需要枚举所有 \((x,y)\),这一步花了太多时间。我们考虑优化这一点。假设我们找到了第一个 \((x,1,y)\),此时如果存在合法方案并且 \((x,1,y)\) 在方案中并非分属于 A B C(即同属于 B),那么说明存在一个 \((x',y')\),使得 \(1,x,y\in B\)\(x'\in A\)\(y'\in C\) 。所以我们不断地去找有没有可以把之前枚举的所有点放在 B 里的新的 \(x'\)\(y'\),一旦找不到了,就说明在存在合法方案的情况下,最后枚举到的 \(x'\)\(y'\) 一定就在方案中分别属于 A 和 C,而之前枚举的所有点包括 1 都属于 B,然后再一个个把剩下的点加入即可,复杂度可以做到 \(O(n^2)\)
题解里写到用 random-shuffle 做到 n 方,不过没怎么搞清楚题解的意思。

这里给出第二种做法的代码

#include<bits/stdc++.h>
using ll=long long;
using namespace std;
void solve();
int main(){int t=1;// cin>>t;while(t--)solve();return 0;
}const int N=503;
int a[N][N];
int st[N];
void solve(){int n;cin>>n;for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++){cin>>a[i][j];a[j][i]=a[i][j]^1;}for(int i=2;i<=n;i++){if(a[i][1])st[i]=1;else st[i]=2;}auto add=[&](int u){st[u]=0;for(int i=1;i<=n;i++)if(st[i]){if(st[i]==1&&a[u][i])st[i]=3;if(st[i]==2&&a[i][u])st[i]=3;}};int x=-1,y=-1; // x->1->yfor(int i=2;i<=n;i++)if(st[i]==1){for(int j=2;j<=n;j++){if(a[j][i]&&st[j]==2){add(i);add(j);x=i;y=j;break;}}}if(x==-1){cout<<"0 0 0\n";return;}st[x]=-1;//Ast[y]=-2;//Cvector<int>A,B,C;A.push_back(x);C.push_back(y);for(int i=1;i<=n;i++)if(st[i]==0)B.push_back(i);for(int i=1;i<=n;i++){if(st[i]>0){int wb=a[i][1],wa=a[i][x],wc=a[i][y];for(auto j:A)if(wa!=-1&&(wa^a[i][j])){wa=-1;break;}for(auto j:B)if(wb!=-1&&(wb^a[i][j])){wb=-1;break;}for(auto j:C)if(wc!=-1&&(wc^a[i][j])){wc=-1;break;}if(wb==1&&wc==0)A.push_back(i);else if(wc==1&&wa==0)B.push_back(i);else if(wa==1&&wb==0)C.push_back(i);else{// cerr<<"!\n";cout<<"0 0 0\n";return;}}}cout<<A.size()<<" "<<B.size()<<" "<<C.size()<<endl;for(auto j:A)cout<<j<<" ";cout<<endl;for(auto j:B)cout<<j<<" ";cout<<endl;for(auto j:C)cout<<j<<" ";cout<<endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/62340.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

同花顺--涨停板改变颜色

复制以下代码 IF(C>=REF(C,1)*1.095 AND C=H) RETURN "涨停"; 然后进行操作: 1、打开同花顺软件,右击K线,单击修改K线2、光标挪到代码首行行首,回车换行3、粘贴一下4、点击设置标志5、命名为涨停,选颜色,填充打勾6、点击确定

关于零值和nil

1. 零值 零值是指当你声明变量(分配内存)并未显式初始化时,始终为你的变量自动设置一个默认初始值的策略。 对于值类型:布尔类型为 false, 数值类型为 0,字符串为 "",数组和结构会递归初始化其元素或字段,即其初始值取决于元素或字段。 对于引用类型: 均为 n…

利用AutoGpt将任何模型支持o1模型的推理实现

利用AutoGpt将任何模型支持o1模型的推理实现 相信大家都对于OpenAI最新出的o1模型都非常关注,它已经能通过推理让回复的效果更加理想, 但是目前o1的限制太大,而且使用o1至少也是需要购买OpenAI官方的会员价格也在20美刀(好贵!!),于是乎社区出现非常多相似的实现,通过更…

C语言类型与强制类型转换

目录类型关键字sizeof如何理解强制类型转化不同类型的0null字符设备(补充) char有有符号和无符号两种类型,字符是无符号类型.(补充) getchar的返回值为什么是int键盘输入的内容,以及往显示器中打印的内容,都是字符 --> 键盘/显示器称为字符设备 类型C语言为何有类型? 让我们…

访问Github卡顿甚至进不去的解决办法(适用于Windows)

本文使用Watt Tookit(原Steam++)解决了Github在国内访问速度卡顿甚至无反应的问题,通过NDM和镜像网站实现Github大文件高速下载。本文首发自个人博客:点我查看 一、前言 Github 是全球知名的开源宝库,但是对国内用户并不友好。当我们在浏览器中输入www.github.com时,如果…

如何在 ASP.NET Core Web API 方法执行前后 “偷偷“ 作一些 “坏“ 事?初识 ActionFilterAttribute

ActionFilterAttribute 是一种作用于控制器 Action 方法的特性(Attribute),通过它,你可以在操作执行前后、异常处理时等不同的阶段插入自定义逻辑。 比如在执行操作方法之前修改请求参数、记录日志、进行权限验证等操作,在执行操作方法之后发送邮件、同步数据等等。 本文主…

看看mysql干的恶心事

MySQL是一个关系型数据库管理系统,最初由瑞典的MySQL AB公司开发。该公司后来被Sun公司收购,而Sun公司随后又被Oracle公司收购。因此,目前MySQL属于Oracle旗下的产品。MySQL以其体积小、速度快、总体拥有成本低的特点,成为了最流行的关系型数据库管理系统之一,特别是在WEB…

LoRaWAN网关价格干穿地板了

曾经LoRaWAN网关要上万块钱一台,后来卷到千把块钱,现在可以卷到500以内,还支持4G/ETH/WIFI,应该也是没谁了。 先上图片1.1 产品特点 ◆ 高性能嵌入式硬件平台 ◆ 使用工业级 Cat.1 4G 模块 ◆ 宽压输入 DC 9~28V,工业级稳定性 ◆ 群脉冲:电源2kV,通讯线4kV ◆ 湿度范围…