[cf587D]Duff in Mafia
二分最大边权,即有些边强制不能被选
接下来,即任意一点上某两边不能同时被选,以及任意一点上颜色相同的两边必须被选择一条
这些限制都可以用2-sat的形式来描述(强制不能选即连边"选->不选"),但后两类的边数达到了$o(m^{2})$,时间复杂度上无法接受
当一个节点上有一种颜色的边出现3次,或有两种颜色的边出现两次,必然不合法,因此第3类限制的边每一个点上至多只有1条,即为$o(n)$
对于第2类限制,即该点上任意一边都要向其余边连线,那么即新建一些点来优化连边
更具体的,假设某个点上相关的边分别对应点$a_{1},a_{2},...,a_{k}$和$a'_{1},a'_{2},...,a_{k}$(后者表示不选),即需要连边$(a_{i},a'_{j})$(其中$i\ne j$)
新建$s_{1},s_{2},...,s_{k}$,连边$(s_{i},s_{i-1})$和$(s_{i},a'_{i})$,再连边$(a_{i},s_{i-1})$即实现了连边$(a_{i},a'_{j})$(其中$j<i$)
对于$j>i$类似,即连边$(s'_{i},s'_{i+1})$和$(s'_{i},a'_{i})$,再连边$(a_{i},s'_{i+1})$即可
综上,即将边数优化为$o(m)$,可以通过
(关于这个,也可以理解为前后缀的构造)

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 struct Edge{
5 int nex,to,color,len;
6 }edge[N];
7 vector<int>v,ans,A[N*3],B[N*3];
8 map<int,int>tot,lst;
9 int V,E,n,m,x,y,c,z,scc,head[N],vis[N*3],dfn[N*3],bl[N*3];
10 void add_edge(int x,int y,int c,int z){
11 edge[E].nex=head[x];
12 edge[E].to=y;
13 edge[E].color=c;
14 edge[E].len=z;
15 head[x]=E++;
16 }
17 void add_2sat(int x,int y){
18 A[x].push_back(y);
19 B[y].push_back(x);
20 }
21 void del_2sat(int x,int y){
22 A[x].pop_back();
23 B[y].pop_back();
24 }
25 void dfs1(int k){
26 if (vis[k])return;
27 vis[k]=1;
28 for(int i=0;i<A[k].size();i++)dfs1(A[k][i]);
29 dfn[++dfn[0]]=k;
30 }
31 void dfs2(int k){
32 if (bl[k])return;
33 bl[k]=scc;
34 for(int i=0;i<B[k].size();i++)dfs2(B[k][i]);
35 }
36 bool calc(int k){
37 for(int i=0;i<E;i+=2)
38 if (edge[i].len>k)add_2sat((i>>1),(i>>1)+m);
39 scc=dfn[0]=0;
40 memset(vis,0,sizeof(vis));
41 memset(bl,0,sizeof(bl));
42 for(int i=0;i<V;i++)
43 if (!vis[i])dfs1(i);
44 for(int i=dfn[0];i;i--)
45 if (!bl[dfn[i]]){
46 scc++;
47 dfs2(dfn[i]);
48 }
49 bool flag=1;
50 for(int i=0;i<m;i++)
51 if (bl[i]==bl[i+m]){
52 flag=0;
53 break;
54 }
55 for(int i=0;i<E;i+=2)
56 if (edge[i].len>k)del_2sat((i>>1),(i>>1)+m);
57 return flag;
58 }
59 int main(){
60 scanf("%d%d",&n,&m);
61 memset(head,-1,sizeof(head));
62 for(int i=1;i<=m;i++){
63 scanf("%d%d%d%d",&x,&y,&c,&z);
64 add_edge(x,y,c,z);
65 add_edge(y,x,c,z);
66 }
67 V=(m<<1);
68 for(int i=1;i<=n;i++){
69 x=y=-1;
70 v.clear(),tot.clear(),lst.clear();
71 for(int j=head[i];j!=-1;j=edge[j].nex){
72 tot[edge[j].color]++;
73 if (tot[edge[j].color]>2){
74 printf("No");
75 return 0;
76 }
77 if (tot[edge[j].color]==2){
78 if ((x>=0)&&(y>=0)){
79 printf("No");
80 return 0;
81 }
82 x=(lst[edge[j].color]>>1);
83 y=(j>>1);
84 }
85 lst[edge[j].color]=j;
86 v.push_back(j>>1);
87 }
88 if ((x>=0)&&(y>=0)){
89 add_2sat(x+m,y);
90 add_2sat(y+m,x);
91 }
92 for(int j=0;j<v.size();j++){
93 add_2sat(V+j,v[j]+m);
94 add_2sat(V+j+v.size(),v[j]+m);
95 }
96 for(int j=1;j<v.size();j++){
97 add_2sat(V+j,V+j-1);
98 add_2sat(V+j+v.size()-1,V+j+v.size());
99 add_2sat(v[j],V+j-1);
100 add_2sat(v[j-1],V+j+v.size());
101 }
102 V+=(v.size()<<1);
103 }
104 int l=0,r=0x3f3f3f3f;
105 while (l<r){
106 int mid=(l+r>>1);
107 if (calc(mid))r=mid;
108 else l=mid+1;
109 }
110 if (l==0x3f3f3f3f)printf("No");
111 else{
112 calc(l);
113 for(int i=0;i<m;i++)
114 if (bl[i]>bl[i+m])ans.push_back(i+1);
115 printf("Yes\n%d %d\n",l,ans.size());
116 for(int i=0;i<ans.size();i++)printf("%d ",ans[i]);
117 }
118 }
[cf587D]Duff in Mafia的更多相关文章
- 【CF587D】Duff in Mafia 二分+前缀优化建图+2-SAT
[CF587D]Duff in Mafia 题意:给你一张n个点m条边的无向图,边有颜色和边权.你要从中删去一些边,满足: 1.任意两条删掉的边没有公共的顶点.2.任意两条剩余的.颜色相同的边没有公共 ...
- Codeforces 587D - Duff in Mafia(2-SAT+前后缀优化建图)
Codeforces 题面传送门 & 洛谷题面传送门 2-SAT hot tea. 首先一眼二分答案,我们二分答案 \(mid\),那么问题转化为,是否存在一个所有边权都 \(\le mid\ ...
- 2021record
2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...
- 2-SET 前缀优化建图
1, Duff in Mafia CodeForces - 587D 2, Ants CodeForces - 1007D
- cf Round 587
A.Duff and Weight Lifting(思维) 显然题目中只有一种情况可以合并 2^a+2^a=2^(a+1).我们把给出的mi排序一下,模拟合并操作即可. # include <c ...
- Codeforces Round #326 (Div. 2) B. Pasha and Phone C. Duff and Weight Lifting
B. Pasha and PhonePasha has recently bought a new phone jPager and started adding his friends' phone ...
- 【转】Duff's Device
在看strcpy.memcpy等的实现发现用了内存对齐,每一个word拷贝一次的办法大大提高了实现效率,参加该blog(http://totoxian.iteye.com/blog/1220273). ...
- [BZOJ1163][BZOJ1339][Baltic2008]Mafia
[BZOJ1163][BZOJ1339][Baltic2008]Mafia 试题描述 匪徒准备从一个车站转移毒品到另一个车站,警方准备进行布控. 对于每个车站进行布控都需要一定的代价,现在警方希望使用 ...
- Codeoforces 558 B. Duff in Love
// B. Duff in Love time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
随机推荐
- css的公共属性及原因
在我们写多个网页的时候,会发现总会遇到很多相同的css样式,若是每次都要在网页代码中写,会浪费时间,同时也会消耗浏览器和计算机的性能.因此,我个人将我敲代码过程中的经常用到的css样式总结了一下.再用 ...
- 实现一个简单的侧边导航Winform程序框架
目录 简介 实现导航面板 实现方法 使用方法 实现标题栏 窗体拖拽及最大化 自定义窗体按钮 标题显示 按钮设置 实现状态栏 整体使用 参考文章 简介 每次新项目都要想着界面怎么设计好,但想来想去上位机 ...
- 微信小程序 开发 “婚礼邀请函”
成品展示: 5个页面 我们来讲解哈(上面地图位置随便定的点) 1.首页开发 一开始进来显示首页 然后默认开始播放背景音乐,这个背景音乐点击右上角图标可以暂停(有动画),然后点击新郎和新娘文字可以调到 ...
- Conda 创建和删除虚拟环境
1.检验当前conda的版本 conda -V C:\Users>conda -V conda 4.10.1 2.conda 常用的命令 查看已有的虚拟环境 C:\Users>conda ...
- (课内)信安数基RSA-level1&&2
注:(不求甚解的)攻击原理 以及(浅层的)算法解释已在图片中给出:文字部分主要讲一些python语法的东西. 代码需要库 gmpy2和libnum:加密算法还需要Crypto.Util.number ...
- 【UE4 C++】 外部图片读取、Texture 保存 png
蓝图版 导入外部图片 file://E:/UE___Projects_Test/MyProjectAAA/Plugins/WXimage.jpg 导出图图片 一般导出 .hdr 文件 导出 png 设 ...
- OO_JAVA_表达式求导_单元总结
OO_JAVA_表达式求导_单元总结 这里引用个链接,是我写的另一份博客,讲的是设计层面的问题,下面主要是对自己代码的单元总结. 程序分析 (1)基于度量来分析自己的程序结构 第一次作业 程序结构大致 ...
- Spring Security Resource Server的使用
Spring Security Resource Server的使用 一.背景 二.需求 三.分析 四.资源服务器认证流程 五.实现资源服务器 1.引入jar包 2.资源服务器配置 3.资源 六.测试 ...
- 关于麦克风的参数介绍 - 驻极体麦克风(ECM)和硅麦(MEMS)
1.麦克风的分类1.1.动圈式麦克风(Dynamic Micphone)原理:基本构造包含线圈.振膜.永久磁铁三部分.当声波进入麦克风,振膜受到声波的压力而产生振动,与振膜在一起的线圈则开始在磁场中移 ...
- 单片机stm32串口分析
stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...