Codeforces Round #375 (Div. 2) -- E. One-Way Reform(dfs求欧拉回路)

本文介绍了一种将无向图中的边定向的方法,目标是最小化入度与出度不等的顶点数量。通过引入虚拟节点连接奇度节点并寻找欧拉回路来实现最优定向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大体题意:

给你一个无向图,要求不能增边的,给边定向,使得图中入度等于出度的点尽可能多,输出结果,和边的方向!

思路:

赛后补得,请教了学长的思路(想了一天= =),感觉思路很巧妙:

首先,无向图中奇度点的个数一定是偶数个(我才知道,感觉很神奇= = ~)

那么我们可以把每个奇度的点与一个新的虚拟结点相连,这样最后我们会得到一个全都是偶数度数的无向图,那么必然存在一条欧拉回路,我们只需要求出所有的欧拉回路,这就是结果!结果在把于虚拟节点相连的边删去即可!

想一想就是这么回事,欧拉回路 经过每个边一次,这样就保证了入度等于出度,那么答案也就是偶数度数的个数!

关于存边有两个方法:

用邻接表或者 set存。

邻接表 直接判断边是否访问过即可!

对于set 更直接,直接删除访问过的点即可!

注意:

1.用邻接表注意数组大小要适当,因为虚拟节点的存在,实际中的边 比你想像的要多不少  错了N遍了~~

2.在一个就是dfs时要dfs所有的点!这里也错了好几遍,因为这个图可能不是全连通的,那么就需要dfs所有的点!

详细见代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 40000 + 1;
const int inf = 0x3f3f3f3f;
struct Node{
    int v, next;
}p[maxn<<1];
int e,d[300],head[300];
bool vis[maxn<<1];
vector<pair<int,int> >path;
void addedge(int u,int v){
    p[e].v = v;
    p[e].next = head[u];
    head[u] = e++;
}
void dfs(int k){
    for (int i = head[k]; i != -1; i = p[i].next){
        if (vis[i])continue;
        vis[i] = vis[i^1] = 1;
        int v = p[i].v;
        path.push_back(make_pair(k,v));
//        printf("^^^ %d %d\n",k,v);
        dfs(v);
    }
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(head,-1,sizeof head);
        memset(d,0,sizeof d);
        memset(vis,0,sizeof vis);
        path.clear();
        e = 0;
        int n, m, s = 1;
        scanf("%d %d",&n, &m);
        for (int i = 0; i < m; ++i){
            int u,v;
            scanf("%d %d",&u, &v);
            addedge(u,v);
            addedge(v,u);
            s = u;
            d[u]++,d[v]++;
        }
        int ans = 0;
        for (int i = 1; i <= n; ++i){
            if (d[i] & 1){
                ++ans;
//                printf("%d\n",i);
                addedge(i,233);
                addedge(233,i);
            }
        }
        for (int i = 1; i <= n; ++i){
            dfs(i);
        }
        int len = path.size();
        printf("%d\n",n - ans);
        for (int i = 0; i < len; ++i){
            if (path[i].first == 233 || path[i].second == 233)continue;
            printf("%d %d\n",path[i].first,path[i].second);
        }
    }

    return 0;
}


/**
1
7 2
3 7
4 2
**/

E. One-Way Reform
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

There are n cities and m two-way roads in Berland, each road connects two cities. It is known that there is no more than one road connecting each pair of cities, and there is no road which connects the city with itself. It is possible that there is no way to get from one city to some other city using only these roads.

The road minister decided to make a reform in Berland and to orient all roads in the country, i.e. to make each road one-way. The minister wants to maximize the number of cities, for which the number of roads that begins in the city equals to the number of roads that ends in it.

Input

The first line contains a positive integer t (1 ≤ t ≤ 200) — the number of testsets in the input.

Each of the testsets is given in the following way. The first line contains two integers n and m (1 ≤ n ≤ 2000 ≤ m ≤ n·(n - 1) / 2) — the number of cities and the number of roads in Berland.

The next m lines contain the description of roads in Berland. Each line contains two integers u and v (1 ≤ u, v ≤ n) — the cities the corresponding road connects. It's guaranteed that there are no self-loops and multiple roads. It is possible that there is no way along roads between a pair of cities.

It is guaranteed that the total number of cities in all testset of input data doesn't exceed 200.

Pay attention that for hacks, you can only use tests consisting of one testset, so t should be equal to one.

Output

For each testset print the maximum number of such cities that the number of roads that begins in the city, is equal to the number of roads that ends in it.

In the next m lines print oriented roads. First print the number of the city where the road begins and then the number of the city where the road ends. If there are several answers, print any of them. It is allowed to print roads in each test in arbitrary order. Each road should be printed exactly once.

Example
input
2
5 5
2 1
4 5
2 3
1 3
3 5
7 2
3 7
4 2
output
3
1 3
3 5
5 4
3 2
2 1
3
2 4
3 7



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值