CF 528C 欧拉回路构造

C. Data Center Drama
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The project of a data center of a Big Software Company consists of n computers connected by m cables. Simply speaking, each computer can be considered as a box with multiple cables going out of the box. Very Important Information is transmitted along each cable in one of the two directions. As the data center plan is not yet approved, it wasn’t determined yet in which direction information will go along each cable. The cables are put so that each computer is connected with each one, perhaps through some other computers.

The person in charge of the cleaning the data center will be Claudia Ivanova, the janitor. She loves to tie cables into bundles using cable ties. For some reasons, she groups the cables sticking out of a computer into groups of two, and if it isn’t possible, then she gets furious and attacks the computer with the water from the bucket.

It should also be noted that due to the specific physical characteristics of the Very Important Information, it is strictly forbidden to connect in one bundle two cables where information flows in different directions.

The management of the data center wants to determine how to send information along each cable so that Claudia Ivanova is able to group all the cables coming out of each computer into groups of two, observing the condition above. Since it may not be possible with the existing connections plan, you are allowed to add the minimum possible number of cables to the scheme, and then you need to determine the direction of the information flow for each cable (yes, sometimes data centers are designed based on the janitors’ convenience…)

Input
The first line contains two numbers, n and m (1 ≤ n ≤ 100 000, 1 ≤ m ≤ 200 000) — the number of computers and the number of the already present cables, respectively.

Each of the next lines contains two numbers ai, bi (1 ≤ ai, bi ≤ n) — the indices of the computers connected by the i-th cable. The data centers often have a very complex structure, so a pair of computers may have more than one pair of cables between them and some cables may connect a computer with itself.

Output
In the first line print a single number p (p ≥ m) — the minimum number of cables in the final scheme.

In each of the next p lines print a pair of numbers ci, di (1 ≤ ci, di ≤ n), describing another cable. Such entry means that information will go along a certain cable in direction from ci to di.

Among the cables you printed there should be all the cables presented in the original plan in some of two possible directions. It is guaranteed that there is a solution where p doesn’t exceed 500 000.

If there are several posible solutions with minimum possible value of p, print any of them.

Examples
input
4 6
1 2
2 3
3 4
4 1
1 3
1 3
output
6
1 2
3 4
1 4
3 2
1 3
1 3
input
3 4
1 2
2 3
1 1
3 3
output
6
2 1
2 3
1 1
3 3
3 1
1 1

题意:题目很长,大致就是给一个连通无向图,加最少的边,并给所有边定向,使得每个点的入度出度均为偶数。

做法:度数为奇数的点有偶数个,两两连边,构成欧拉回路。如果欧拉回路长为奇数,则给1加个自环。然后在回路上方向交替变化即可。用一个multiset支持删除双向边的操作。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=205000;

int indegree[maxn];
multiset<int>g[maxn];
int a[maxn];
int tot;
int tag;

void dfs(int st)
{
    while(!g[st].empty()){
        int to=*(g[st].begin());
        g[st].erase(g[st].begin());
        g[to].erase(g[to].find(st));
        dfs(to);
        tag^=1;
        if(tag)printf("%d %d\n", to, st);
        else printf("%d %d\n", st, to);
    }
}

int main()
{
    memset(indegree, 0, sizeof(indegree));
    int n, m;
    scanf("%d%d", &n, &m);
    int cnt=0;
    for(int i=1;i<=m;i++){
        int x, y;
        scanf("%d%d", &x, &y);
        indegree[y]++;
        indegree[x]++;
        g[x].insert(y);
        g[y].insert(x);
        cnt++;
    }
    tot=0;
    for(int i=1;i<=n;i++){
        if(indegree[i]%2)a[++tot]=i;
    }
    for(int i=1;i<=tot;i+=2){
        g[a[i]].insert(a[i+1]);
        g[a[i+1]].insert(a[i]);
        cnt++;
    }
    if(cnt%2){
        cnt++;
        printf("%d\n", cnt);
        printf("1 1\n");
    }
    else printf("%d\n", cnt);
    tag=0;
    dfs(1);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值