令$e_{G}(a)$和$o_{G}(a)$分别表示在图$G$中从1到$a$的长度为奇数/偶数的最短路(若该类最短路不存在则为$\infty$),不难得到有以下结论——$f_{G}(a,b)=\begin{cases}[b\ge e_{G}(a)]&(b\equiv 0(mod\ 2))\\ [b\ge o_{G}(a)]&(b\equiv 1(mod\ 2))\end{cases}$

根据这个结论,即要求$\forall a,e_{G}(a)=e_{G'}(a)$且$o_{G}(a)=o_{G'}(a)$

先对原图$G$求出所有$e_{G}(a)$和$o_{G}(a)$,将$a$拆为$a_{0}$和$a_{1}$,并对边$(a,b)$连$(a_{0},b_{1})$和$(a_{1},b_{0})$,最后从$1_{0}$出发bfs即可,时间复杂度为$o(n)$

记$G'$的边集为$E$,那么$\forall a,e_{G}(a)=e_{G'}(a)$且$o_{G}(a)=o_{G'}(a)$当且仅当满足以下两个条件:

1.$(a,b)\in E,|e_{G}(a)-o_{G}(b)|=1$且$|e_{G}(b)-o_{G}(a)|=1$(特别的,定义$|\infty-\infty|=1$)

2.$\forall e_{G}(a)\ne 0,\infty,\exists (a,b)\in E,e_{G}(a)=o_{G}(b)+1$且$\forall o_{G}(a)\ne \infty,\exists (a,b)\in E,o_{G}(a)=e_{G}(b)+1$

(关于这个结论,必要性显然,充分性拆点后对距离从小到大归纳即可)

若存在$a$满足$e_{G}(a)=\infty$,那么根据第1个条件,与其相连的点$o_{G}(b)=\infty$,以此类推,所有点(原图连通)$b$都满足$e_{G}(b)=\infty$或$o_{G}(b)=\infty$($o_{G}(a)=\infty$同理)

此时,对于第2个条件,除1以外(1没有限制)每一个点仅有1维有限制,只需要连向一个可以使其该维满足第2个条件的点,显然这样的点必然存在,最终的边数即为$n-1$

(也即原图没有奇环,不能调整奇偶性,构造方案即取以1为根的最短路径树)

考虑这种情况后,即$\forall a,e_{G}(a),o_{G}(a)\ne \infty$,将其作为点$(\min(e_{G}(a),o_{G}(a)),\max(e_{G}(a),o_{G}(a)))$,并将所有点$(x,y)$按照$x+y$从小到大排序、$x+y$相同时$x$从小到大排序

现在,我们从前往后,依次考虑当前点$(x,y)$,去连边满足其第2个条件

如果之前存在点$(x-1,y+1)$“未完全合法”,显然从中任选一个连边即可,连边后$(x,y)$也成为一个“未完全合法”的点(还需要与$(x\pm 1,y-1)$连边),暂不处理

否则,如果之前存在点$(x-1,y-1)$,直接连边即可,即满足条件

否则,再找到$(x-1,y+1)$连边(若$x=0$时不需要连,否则必然存在),并作为“未完全合法”的点

另外,若$y=x+1$且$(x,y)$作为“未完全合法”的点,注意到$(x+1,y-1)$实际上是$(x,y)$自己,因此若之间存在点$(x,y)$“未完全合法”,将这两点连边即可(并取消两点“未完全合法”的标记)

最终,对于剩下的“未完全合法”的点$(x,y)$,找到$(x\pm 1,y-1)$连边即可,由于必然存在,即边数加上“未完全合法”的点数量即可

(当然这个数量也可以在修改过程中顺便加上)

由此,用map维护$(x,y)$上“未完全合法”的点数量即可支持此过程,时间复杂度为$o(n\log n)$

(关于这一做法的正确性,即是一个贪心,比较显然)

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 struct Edge{
5 int nex,to;
6 }edge[N<<2];
7 queue<int>q;
8 vector<pair<int,int> >v;
9 map<int,int>mat_vis[N],mat[N];
10 int E,t,n,m,x,y,ans,head[N],vis[N],d[N];
11 void add(int x,int y){
12 edge[E].nex=head[x];
13 edge[E].to=y;
14 head[x]=E++;
15 }
16 void bfs(){
17 d[1]=0;
18 q.push(1);
19 vis[1]=1;
20 while (!q.empty()){
21 int k=q.front();
22 q.pop();
23 for(int i=head[k];i!=-1;i=edge[i].nex)
24 if (!vis[edge[i].to]){
25 d[edge[i].to]=d[k]+1;
26 q.push(edge[i].to);
27 vis[edge[i].to]=1;
28 }
29 }
30 }
31 int main(){
32 scanf("%d",&t);
33 while (t--){
34 scanf("%d%d",&n,&m);
35 E=ans=0;
36 for(int i=0;i<=(n<<1);i++){
37 head[i]=d[i]=-1;
38 vis[i]=0;
39 mat_vis[i].clear(),mat[i].clear();
40 }
41 for(int i=1;i<=m;i++){
42 scanf("%d%d",&x,&y);
43 add(x,y+n);
44 add(y+n,x);
45 add(x+n,y);
46 add(y,x+n);
47 }
48 bfs();
49 if (d[n+1]<0){
50 printf("%d\n",n-1);
51 continue;
52 }
53 v.clear();
54 for(int i=1;i<=n;i++)v.push_back(make_pair(min(d[i],d[i+n]),max(d[i],d[i+n])));
55 sort(v.begin(),v.end());
56 for(int i=0;i<n;i++)mat_vis[v[i].first][v[i].second]=1;
57 for(int i=0;i<n;i++){
58 x=v[i].first,y=v[i].second;
59 if ((x)&&(mat[x-1][y+1])){
60 mat[x-1][y+1]--;
61 mat[x][y]++;
62 ans++;
63 }
64 else{
65 if ((x)&&(mat_vis[x-1][y-1]))ans++;
66 else{
67 mat[x][y]++;
68 ans+=1+(x>0);
69 }
70 }
71 if ((y==x+1)&&(mat[x][y]>=2)){
72 mat[x][y]-=2;
73 ans--;
74 }
75 }
76 printf("%d\n",ans);
77 }
78 }

[luogu7417]Minimizing Edges P的更多相关文章

  1. 读书笔记-《Training Products of Experts by Minimizing Contrastive Divergence》

    Training Products of Experts by Minimizing Contrastive Divergence(以下简称 PoE)是 DBN 和深度学习理论的 肇始之篇,最近在爬梳 ...

  2. 【OpenMesh】Some basic operations: Flipping and collapsing edges

    这一节中你将学到一些OpenMesh中早已提供的基础操作. 内容包括三角形网格边的翻转以及通过连接邻接的顶点边缘折叠. 三角形网格的翻转(Flipping edges) 考虑到两个邻接面的三角形网格中 ...

  3. R 网络图 nodes,edges属性计算

    前面提到了用R画网络图,免不了要对网络图nodes和edges的特征做一些统计.分享下我的代码: ########## nodes edges的统计########### # ####nodes的度有 ...

  4. Google SketchUp Cookbook: (Chapter 3) Intersection Edges: Cutting and Trimming

    软件环境 SketchUp Pro 2018 参考书籍 Google SketchUp Cookbook Trimming an Object 使用 Intersect with Model 裁剪物体 ...

  5. CF962F Simple Cycles Edges

    CF962F Simple Cycles Edges 给定一个连通无向图,求有多少条边仅被包含在一个简单环内并输出 \(n,\ m\leq10^5\) tarjan 首先,一个连通块是一个环,当且仅当 ...

  6. atcoder NIKKEI Programming Contest 2019 E - Weights on Vertices and Edges

    题目链接:Weights on Vertices and Edges 题目大意:有一个\(n\)个点\(m\)条边的无向图,点有点权,边有边权,问至少删去多少条边使得对于剩下的每一条边,它所在的联通块 ...

  7. Maya cmds filterExpand 列出 选择的 uvs vertices faces edges 等 component 类型

    Maya cmds filterExpand 列出 选择的 uvs vertices faces edges 等 component 类型 cmds.ls() 的 flags 中没有指明 uvs 等这 ...

  8. Maya cmds pymel 快速选择hard edges(硬边)

    Maya cmds pymel 快速选择hard edges(硬边) import maya.cmds as cmds cmds.polySelectConstraint(m = 3, t = 0x8 ...

  9. Codeforces 160D Edges in MST tarjan找桥

    Edges in MST 在用克鲁斯卡尔求MST的时候, 每个权值的边分为一类, 然后将每类的图建出来, 那些桥就是必须有的, 不是桥就不是必须有. #include<bits/stdc++.h ...

随机推荐

  1. xLua中C#调用Lua

    C#调用Lua 一.前提 这里使用的是XLua框架,需要提前配置xlua,设置加载器路径: 可以参考之前的Blog:<xlua入门基础>: 二.C#调用Lua全局变量 lua中所有的全局变 ...

  2. C#开发BIMFACE系列45 服务端API之创建离线数据包

    BIMFACE二次开发系列目录     [已更新最新开发文章,点击查看详细] BIMFACE的常规应用方式有公有云与私有化部署两种方式,并且浏览模型或者图纸需要使用ViewToken,ViewToke ...

  3. bzoj4094 && luogu3097 最优挤奶

    题目大意: 给定n个点排成一排,每个点有一个点权,有m次修改,每次改变某个点的点权并将最大点独立集计入答案,输出最终的答案 其中\(n\le 40000\ , \ m\le 50000\) QWQ说实 ...

  4. centos7谷歌chrome内网部署演示

    上传需要的包,注释网关创建内网环境 [root@localhost ~]# ls anaconda-ks.cfg chrome mcw4 mcw4.tar.gz mcwchromerpm.tar.gz ...

  5. logging的基本使用

    logging模块打印log的时候主要有一下几个,级别顺序:CRITICAL>ERROR>WARNING>INFO>DEBUG: 1.日志输出到file: import log ...

  6. Scrum Meeting 0509

    零.说明 日期:2021-5-9 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 qsy PM&前端 测试 测试 cyy ...

  7. 基于docker-compose搭建sonarqube代码质量检测平台

    一.需求 在我们开发的过程中,难免有时候代码写的不规范,或存在一些静态的bug问题,这个时候一个良好的代码检查工具就很有必要,而sonarqube正好可以满足整个要求. 二. docker-compo ...

  8. 模拟赛18 T1 施工 题解

    前言: 真的是不容易啊.这个题在考场上想到了最关键的性质,但是没写出来. 后来写出来,一直调,小错不断. 没想到改的最后一个错误是两个int 乘起来爆了int 其实最后我还是觉得复杂度很假.\(n^2 ...

  9. 关于麦克风的参数介绍 - 驻极体麦克风(ECM)和硅麦(MEMS)

    1.麦克风的分类1.1.动圈式麦克风(Dynamic Micphone)原理:基本构造包含线圈.振膜.永久磁铁三部分.当声波进入麦克风,振膜受到声波的压力而产生振动,与振膜在一起的线圈则开始在磁场中移 ...

  10. 计算机网络之网络层IP组播(IGMP、组播路由选择协议、组播地址)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105318560 学习课程:<2019王道考研计算机网络> 学习目的 ...