@codeforces - 1186F@ Vus the Cossack and a Graph
@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的更多相关文章
- Codeforces 1186F - Vus the Cossack and a Graph 模拟乱搞/欧拉回路
题意:给你一张无向图,要求对这张图进行删边操作,要求删边之后的图的总边数 >= ceil((n + m) / 2), 每个点的度数 >= ceil(deg[i] / 2).(deg[i]是 ...
- 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 ...
- codeforces 1186C Vus the Cossack and Strings
题目链接:https://codeforc.es/contest/1186/problem/C 题目大意:xxxxx(自认为讲不清.for instance) 例如:a="01100010& ...
- 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 ...
- 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 ...
- 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 ...
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces 1109D. Sasha and Interesting Fact from Graph Theory
Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 解题思路: 这题我根本不会做,是周指导带飞我. 首先对于当前已经有 \(m ...
- CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)
思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...
随机推荐
- neo4j遍历和图算法
阅读更多 这篇blog主要和大家分享一下neo4j中是如何对节点进行遍历,和其中集成的图论的一些常用算法. 遍历 http://docs.neo4j.org.cn/tutorials-java-emb ...
- 为GitLab配置邮件服务
修改配置文件:/etc/gitlab/gitlab.rb ####################################################################### ...
- 初探Druid
说到连接池,最常见的就是dbcp和c3p0,关于druid,官方定义是为监控而生的数据库连接池. 官方中文文档地址:https://github.com/alibaba/druid/wiki/%E5% ...
- 【CodeVS】2750 心系南方灾区
2750 心系南方灾区 时间限制: 1 s 空间限制: 2000 KB 题目等级 : 青铜 Bronze 题目描述 Description 现在我国南方正在承受百年不遇的大雪.冻雨灾害.北京市已经开始 ...
- nodeJs基础方法
Node.js 是一个基于Chrome javascript 运行时建立的一个平台, 用来方便地搭建快速的 易于扩展的网络应用 Node.js 借助事件驱动, 非阻塞I/O 模型变得轻量和高效, 非常 ...
- 【CS Round #44 (Div. 2 only) C】Check DFS
[链接]点击打开链接 [题意] 给你一个n节点,m条边的无向联通图. 给你一个节点访问的顺序.(1..n的排列) 你可以改变每个点优先访问的出度.(但必须按照dfs的规则); 问你能不能按照所给的访问 ...
- AspNet 常有功能函数1.0
1.net 获取客户端ip方法(此方法不是很准确) public static string GetIP() { string str; if (!string.IsNullOrEmpty(HttpC ...
- HR招聘_(一)_招聘意识
最近接触到一点HR的工作,贯穿始终,故有点心得,与众人分享.言辞不尽之处,万望指点一二.不胜感激. HR招聘_(一)_招聘意识HR招聘_(二)_招聘方法论(招聘原因及原则) HR招聘_(三)_招聘方法 ...
- NYoj 155最短路
//dij #include<stdio.h> #include<string.h> #include<queue> using namespace std; #d ...
- 杨柳絮-Info:太原市多部门通力合作科学治理杨柳飞絮效果好
ylbtech-杨柳絮-Info:太原市多部门通力合作科学治理杨柳飞絮效果好 1.返回顶部 1. 太原市多部门通力合作科学治理杨柳飞絮效果好 2016-04-21 07:16 4月10日,随着气温升高 ...