@description@

给定一个 n 点 m 边的图(n, m<=10^6),记第 i 个点的度数为 di。

现让你保留不超过 (n + m) / 2(向上取整)条边,并且要求新图中第 i 个点的度数 di' 满足 2di' ≥ di。

不难证明它一定有解。现你只需要输出任意一种方案。

input

第一行包含 n 和 m,表示点数与边数。

接下来 m 行每一行包含 2 个整数 ui, vi,描述一条边。

无重边、自环。

output

第一行首先输出保留的边的数量 k。

接下来 k 行每行两个整数 u, v,描述你所保留的边。

sample input

10 20

4 3

6 5

4 5

10 8

4 8

5 8

10 4

9 5

5 1

3 8

1 2

4 7

1 4

10 7

1 7

6 1

9 6

3 9

7 9

6 2

sample output

12

2 1

4 1

5 4

6 5

7 1

7 4

8 3

8 5

9 3

9 6

10 4

10 7

@solution@

好玄妙的题目啊。。。

但我想到的实现好像跟标算不大一样,不过用到的算法大致是一样的。

根据题目,偶数新度数最小为原度数的1/2,奇数新度数最小为(原度数+1)的1/2。

假如所有点的新度数都取最小值,则偶度点连接的边一半被删除,一半被保留;奇度点连接的某一条边保留,然后转为偶度点的情况。

这样将点的度数分奇偶讨论的过程,将某一个点连接的边分为相同大小的集合的操作,有没有让你联想到什么。

欧拉回路。即不重复、不遗漏经历所有边的路径。

欧拉回路可以将一个偶点连接的边分为“入边”和“出边”两类相同个数的边。

同时可以发现,以奇点开始奇点结束的欧拉路径,起点恰好多一条出边,终点恰好多一条入边。

这不和我们刚刚的讨论恰好相一致吗?

考虑欧拉回路,即没有奇数点的情况。

如果该欧拉回路长度为偶数,我们只需要隔一条边保留一条边即可,这样可以保证每一个点入边与出边保留恰好一条,且总边数减至一半。

否则如果长度为奇数,如 (1, 2), (2, 3), (3, 1),我们从第一条边开始隔一条边保留一条边,可以发现最后我们会同时保留第一条与最后一条,而这两条边是相邻的,故我们总边数变为原先的 1/2 再加 1 。

因为没有重边,长度为奇数必然包含两个以上的点,故最多会加 n/2 次。满足题设。

考虑欧拉路径,即起点和终点为奇数点的情况。

如果该欧拉回路长度为奇数,从起点开始隔一条边保留一条边即可。总边数变为原先的 1/2 加 1(因为奇数长度保留的要比删去的多一条)。

否则如果长度为偶数,如 (1, 2), (2, 3), (3, 4), (4, 5),我们从起点开始隔一条边保留一条边之后,再将与终点连接的边保留。总边数变为原先的 1/2 加 1。

最多会有 n 个奇数点,每两个奇数点之间产生一个路径,故最多会加 n/2 次。满足题设。

补充一小点:如何求解多条欧拉路径。你只需要将奇数点两两分组然后连接虚边,跑欧拉回路,然后两个虚边之间夹着的就是一条欧拉路径。如果没有虚边就是一条欧拉回路。

注意题目中给出的图可能不连通,你需要对每个连通块都进行操作。

@accepted code@

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1000000;
const int MAXM = 5000000;
struct edge{
int from, to;
bool flag, tag;
edge *nxt, *rev;
}edges[MAXM + 5], *adj[MAXN + 5], *ecnt = &edges[0];
int fa[MAXN + 5];
int find(int x) {
return fa[x] = (fa[x] == x ? x : find(fa[x]));
}
void addedge(int u, int v, bool t) {
edge *p = (++ecnt), *q = (++ecnt);
p->from = u, p->to = v, p->nxt = adj[u], adj[u] = p;
q->from = v, q->to = u, q->nxt = adj[v], adj[v] = q;
p->flag = q->flag = false, p->tag = q->tag = t;
p->rev = q, q->rev = p;
if( find(u) != find(v) )
fa[find(u)] = find(v);
}
int deg[MAXN + 5]; edge *e[MAXM + 5], *tmp[MAXM + 5];
int ans1[MAXM + 5], ans2[MAXM + 5];
int cnt, tot;
void dfs(int x) {
for(edge *p=adj[x];p;p=adj[x]) {
if( p->flag ) {
adj[x] = adj[x]->nxt;
continue;
}
p->flag = p->rev->flag = true;
adj[x] = adj[x]->nxt; dfs(p->to); e[++cnt] = p;
}
}
void print() {
printf("%d\n", tot);
for(int i=1;i<=tot;i++)
printf("%d %d\n", ans1[i], ans2[i]);
}
int main() {
int n, m; scanf("%d%d", &n, &m);
for(int i=1;i<=n;i++)
fa[i] = i;
for(int i=1;i<=m;i++) {
int u, v; scanf("%d%d", &u, &v);
addedge(u, v, true); deg[u]++, deg[v]++;
}
int lst = 0, fir = 0;
for(int i=1;i<=n;i++) {
if( deg[i] & 1 ) {
if( !lst ) lst = i;
else addedge(lst, i, false), lst = 0;
}
}
for(int i=1;i<=n;i++) {
if( find(i) != i ) continue;
cnt = lst = fir = 0; dfs(i);
for(int j=1;j<=cnt;j++) {
if( !e[j]->tag ) {
if( lst ) {
int siz = 0;
for(int k=lst+1;k<=j-1;k++)
tmp[++siz] = e[k];
if( siz && siz % 2 == 0 ) tmp[siz+1] = tmp[siz], siz++;
for(int k=1;k<=siz;k+=2)
tot++, ans1[tot] = tmp[k]->from, ans2[tot] = tmp[k]->to;
if( siz && siz % 2 == 0 )
tot++, ans1[tot] = tmp[siz]->from, ans2[tot] = tmp[siz]->to;
}
else fir = j;
lst = j;
}
}
if( !lst ) {
for(int j=1;j<=cnt;j+=2)
tot++, ans1[tot] = e[j]->from, ans2[tot] = e[j]->to;
}
else {
int siz = 0;
for(int j=lst+1;j<=cnt;j++)
tmp[++siz] = e[j];
for(int j=1;j<=fir-1;j++)
tmp[++siz] = e[j];
if( siz && siz % 2 == 0 ) tmp[siz+1] = tmp[siz], siz++;
for(int j=1;j<=siz;j+=2)
tot++, ans1[tot] = tmp[j]->from, ans2[tot] = tmp[j]->to;
}
}
print();
}

@details@

虽然题解里说的好像非常自然。

不过要是在做比赛的时候能想得到才有鬼好吧。

求欧拉路的时候通过打 tag 标记访问过的边会 TLE。需要类比网络流中的当前弧优化,将访问过的边直接删除。

@codeforces - 1186F@ Vus the Cossack and a Graph的更多相关文章

  1. Codeforces 1186F - Vus the Cossack and a Graph 模拟乱搞/欧拉回路

    题意:给你一张无向图,要求对这张图进行删边操作,要求删边之后的图的总边数 >= ceil((n + m) / 2), 每个点的度数 >= ceil(deg[i] / 2).(deg[i]是 ...

  2. Codeforces F. Vus the Cossack and Numbers(贪心)

    题目描述: D. Vus the Cossack and Numbers Vus the Cossack has nn real numbers aiai. It is known that the ...

  3. codeforces 1186C Vus the Cossack and Strings

    题目链接:https://codeforc.es/contest/1186/problem/C 题目大意:xxxxx(自认为讲不清.for instance) 例如:a="01100010& ...

  4. CodeForces - 1186 C. Vus the Cossack and Strings (异或)

    Vus the Cossack has two binary strings, that is, strings that consist only of "0" and &quo ...

  5. Vus the Cossack and Strings(Codeforces Round #571 (Div. 2))(大佬的位运算实在是太强了!)

    C. Vus the Cossack and Strings Vus the Cossack has two binary strings, that is, strings that consist ...

  6. Codeforces Round #571 (Div. 2)-D. Vus the Cossack and Numbers

    Vus the Cossack has nn real numbers aiai. It is known that the sum of all numbers is equal to 00. He ...

  7. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  8. Codeforces 1109D. Sasha and Interesting Fact from Graph Theory

    Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 解题思路: 这题我根本不会做,是周指导带飞我. 首先对于当前已经有 \(m ...

  9. CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)

    思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...

随机推荐

  1. drf作业01

    api\urls from django.conf.urls import url from . import views urlpatterns = [ url(r'^cars/$',views.C ...

  2. 洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes【取回文数/数论/字符串】

    题目描述 因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数. 写一个程序来找出范围[a,b](5 <= a < b <= 100,000 ...

  3. Phpstrom 配置php版本语法支持

  4. 【笔记】LR配置ODBC连接数据库进行参数化(mysql )未完待续

    很多时候我们需要大量的参数数据,但是光光靠手填写是非常麻烦的,既然被测对象的数据都在数据库,那么我们直接读取数据库回来就轻松简便很多. data  wizard 提供了一个从ODBC的连接获得数据转化 ...

  5. Matlab 稀疏矩阵函数

    eye 单位矩阵zeros 全零矩阵ones 全1矩阵rand 均匀分布随机阵genmarkov 生成随机Markov矩阵linspace 线性等分向量logspace 对数等分向量logm 矩阵对数 ...

  6. Web渗透三字经

    网络上曾流传一段Web渗透三字经,如下: 用搜索 找注入 没注入 就旁注 没旁注 用0day 没0day 扫目录 找后台 爆账户 传小马 放大马 拿权限 挂页面 放暗链 清数据 清日志 留后门 然后我 ...

  7. 扩展 Microsoft.Owin.Security

    微软在 OWIN 框架中对 OAuth 认证的支持非常好, 使用现有的 OWIN 中间件可以做到: 使用 Microsoft.Owin.Security.OAuth 搭建自己的 OAuth2 服务端, ...

  8. 计算机网络5.2-5 ipv4&路由协议&ipv6

    子网变址技术 子网掩码 默认子网掩码 子网地址 广播地址 一些计算 CIDR 分配举例 地址不必连续分配 sadsdas 网络设备---路由器 输出结构 直接交付与简介交付 IP分组的转发 分属于不同 ...

  9. optim.py cs231n

    n如果有错误,欢迎指出,不胜感激 import numpy as np """ This file implements various first-order upda ...

  10. Bnd教程(1):如何用命令行安装bnd

    1. 如果你用的是MacOS,请运行: brew install bnd 然后运行bnd version看是否安装成功: $ bnd version 4.0.0.201801191620-SNAPSH ...