二分最大边权,即有些边强制不能被选

接下来,即任意一点上某两边不能同时被选,以及任意一点上颜色相同的两边必须被选择一条

这些限制都可以用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的更多相关文章

  1. 【CF587D】Duff in Mafia 二分+前缀优化建图+2-SAT

    [CF587D]Duff in Mafia 题意:给你一张n个点m条边的无向图,边有颜色和边权.你要从中删去一些边,满足: 1.任意两条删掉的边没有公共的顶点.2.任意两条剩余的.颜色相同的边没有公共 ...

  2. Codeforces 587D - Duff in Mafia(2-SAT+前后缀优化建图)

    Codeforces 题面传送门 & 洛谷题面传送门 2-SAT hot tea. 首先一眼二分答案,我们二分答案 \(mid\),那么问题转化为,是否存在一个所有边权都 \(\le mid\ ...

  3. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  4. 2-SET 前缀优化建图

    1, Duff in Mafia CodeForces - 587D 2, Ants CodeForces - 1007D

  5. cf Round 587

    A.Duff and Weight Lifting(思维) 显然题目中只有一种情况可以合并 2^a+2^a=2^(a+1).我们把给出的mi排序一下,模拟合并操作即可. # include <c ...

  6. 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 ...

  7. 【转】Duff's Device

    在看strcpy.memcpy等的实现发现用了内存对齐,每一个word拷贝一次的办法大大提高了实现效率,参加该blog(http://totoxian.iteye.com/blog/1220273). ...

  8. [BZOJ1163][BZOJ1339][Baltic2008]Mafia

    [BZOJ1163][BZOJ1339][Baltic2008]Mafia 试题描述 匪徒准备从一个车站转移毒品到另一个车站,警方准备进行布控. 对于每个车站进行布控都需要一定的代价,现在警方希望使用 ...

  9. Codeoforces 558 B. Duff in Love

    //   B. Duff in Love time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. 洛谷2046 NOI2010海拔

    QwQ题目太长 这里就不复制了 题目 这个题...算是个比较经典的平面图最小割变成对偶图的最短路了QwQ 首先考虑最小割应该怎么做. 有一个性质,就是每个点的海拔要么是1,要么是0 QwQ不过这个我不 ...

  2. PAT (Basic Level) Practice (中文)1007 素数对猜想 (20分)

    1007 素数对猜想 (20分) 让我们定义d​n为:dn = pn+1 − pn,其中p​i是第i个素数.显然有d1 = 1,且对于n > 1有dn是偶数."素数对猜想"认 ...

  3. 更好的 java 重试框架 sisyphus 入门简介

    What is Sisyphus sisyphus 综合了 spring-retry 和 gauva-retrying 的优势,使用起来也非常灵活. 为什么选择这个名字 我觉得重试做的事情和西西弗斯很 ...

  4. 分享一份软件测试项目实战(web+app+h5+小程序)

    大家好,我是谭叔. 本次,谭叔再度出马,给大家找了一个非常适合练手的软件测试项目,此项目涵盖web端.app端.h5端.小程序端,可以说非常之全面. 缘起 在这之前,谭叔已经推出了九套实战教程. 但是 ...

  5. Golang通脉之错误处理

    在实际工程项目中,总是通过程序的错误信息快速定位问题,但是又不希望错误处理代码写的冗余而又啰嗦.Go语言没有提供像Java.C#语言中的try...catch异常处理方式,而是通过函数返回值逐层往上抛 ...

  6. UI自动化测试之Airtest

    官方文档: https://airtest.doc.io.netease.com/ 本文我们讲解下Airtest的使用,主要学习目标有以下几点: (1)认识Airtest (2)了解Airtest能做 ...

  7. Java:ConcurrentHashMap类小记-1(概述)

    Java:ConcurrentHashMap类小记-1(概述) 对 Java 中的 ConcurrentHashMap类,做一个微不足道的小小小小记,分三篇博客: Java:ConcurrentHas ...

  8. Java中的函数式编程(八)流Stream并行编程

    写在前面 在本系列文章的第一篇,我们提到了函数式编程的优点之一是"易于并发编程". Java作为一个多线程的语言,它通过 Stream 来提供了并发编程的便利性. 题外话: 严格来 ...

  9. 【二食堂】Beta - 项目展示

    项目展示 1. 团队介绍 二食堂很难排队 姓名 介绍 职务 刘享 热爱游戏,尤其是RPG和metrovinia类的游戏. 会C/C++, python, java. 后端 左正 一个普通的大学生,Py ...

  10. oo第二次博客-三次电梯调度的总结与反思

    本单元从电梯调度相关问题层层深入,带领我们学习并运用了了多线程相关的知识. 三次电梯调度依次为单电梯单容量.单电梯可携带.多电梯可携带. 一.我的设计 在第一次作业中,使用了最简单的FIFO调度方法. ...