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

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

这些限制都可以用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. .NET Reflector软件破解

    转自:https://blog.csdn.net/zxy13826134783/article/details/89057871 软件和注册机下载地址: 链接:https://pan.baidu.co ...

  2. mysql创建用户及赋予某用户权限(附带基础查看表内容)

    首先登陆mysql 一:show databases;  展示所有数据库(root用户下) 二:use xxx (数据库名)使用use选择数据库 三:show xxx   查看数据库中的表 四:des ...

  3. JavaScript表单输入合法控制

    写在前面 为了提高数据输入的容错性和数据库数据的安全性,除了后端对输入的数据的逻辑判断处理,还可以前端页面高效率处理,从而提高系统的可靠性,下面是这次项目中的自己写的一些符合当时需要的控制. 账号位数 ...

  4. HttpServletRequest 入门

    1. request对象和response对象的原理 request和response对象是由服务器创建的.我们来使用它们 request对象是来获取请求消息,response对象是来设置响应消息 2 ...

  5. Head First Python 代码和实例下载

    http://python.itcarlow.ie/resources.html

  6. Linux搭建SVN服务器详细教程

    前言 本文讲解Linux系统下如何搭建SVN服务器,详细说明各配置项的功能,最终实现可管控多个项目的复杂配置. SVN是subversion的缩写,是一个开放源代码的版本控制系统,通过采用分支管理系统 ...

  7. CentOS 文件管理

    目录 目录管理 目录结构 切换目录 查看目录 创建目录 复制目录 剪切目录 删除目录 文件管理 查看文件 创建文件 复制文件 剪切文件 删除文件 创建链接 目录管理 目录也是一种文件. 蓝色目录,绿色 ...

  8. virtual box搭建虚拟机nat和host only网络配置实用

    virtual box搭建虚拟机nat和host only网络配置实用 一.背景 二.需求 二.设置虚拟机的网络 1.创建一个全局的nat网络 2.添加主机网络管理器 3.设置虚拟机网络 1.网卡1设 ...

  9. Noip模拟44 2021.8.19

    比较惊人的排行榜 更不用说爆零的人数了,为什么联赛会这么难!!害怕了 还要再努力鸭 T1 Emotional Flutter 考场上没切掉的神仙题 考率如何贪心,我们把黑色的条延长$s$,白色的缩短$ ...

  10. 2021.9.21考试总结[NOIP模拟58]

    T1 lesson5! 开始以为是个无向图,直接不懂,跳去T2了. 之后有看了一眼发现可暴力,于是有了\(80pts\). 发现这个图是有拓扑序的,于是可以用拓扑排序找最长路径.先找原图内在最长路径上 ...