CodeForces 723E One-Way Reform

构造。

有一种十分巧妙的方法可以使图中所有度数为偶数的节点,经过每条边定向后,出度和入度都相等。

首先统计每个节点的度数,将度数为奇数的节点与编号为$n+1$的节点连边,这样一来,这张新图变成了每个节点的度数都是偶数的图,必然存在欧拉回路。任意一条欧拉回路都使得原图中度数为偶数的节点的出度与入度相等。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-10;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar();
    x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c))
    {
        x = x * 10 + c - ‘0‘;
        c = getchar();
    }
}

int T,n,m,ans,cnt;
vector<int>v[210];
int f[210];
int ss[100000],ee[100000],t[210][210],p[210][210];

void dfs(int x)
{
    for(int i=v[x].size()-1;i>=0;i--)
    {
        if(t[x][v[x][i]]==1) continue;

        t[x][v[x][i]]=t[v[x][i]][x]=1;
        ss[cnt]=x; ee[cnt]=v[x][i]; cnt++;

        dfs(v[x][i]);
    }
}

int main()
{
    cin>>T;
    for(int cas=1;cas<=T;cas++)
    {
        cin>>n>>m;

        for(int i=1;i<=n+1;i++) v[i].clear();

        memset(f,0,sizeof f);
        memset(p,0,sizeof p);

        for(int i=1;i<=m;i++)
        {
            int a,b; cin>>a>>b;

            v[a].push_back(b);
            v[b].push_back(a);
            f[a]++; f[b]++;
            p[a][b]=p[b][a]=1;
        }

        ans=0; vector<int>x;
        for(int i=1;i<=n;i++)
        {
            if(f[i]%2==0) ans++;
            else x.push_back(i);
        }

        for(int i=0;i<x.size();i++)
        {
            v[n+1].push_back(x[i]);
            v[x[i]].push_back(n+1);
        }

        memset(t,0,sizeof t); cnt=0;
        for(int i=1;i<=n+1;i++) dfs(i);

        printf("%d\n",ans);

        for(int i=0;i<m+(n-ans);i++)
        {
            if(p[ss[i]][ee[i]]==1)
                printf("%d %d\n",ss[i],ee[i]);
        }

    }
    return 0;
}
时间: 2024-08-08 22:09:12

CodeForces 723E One-Way Reform的相关文章

codeforces 723E (欧拉回路)

Problem One-Way Reform 题目大意 给一张n个点,m条边的无向图,要求给每条边定一个方向,使得最多的点入度等于出度,要求输出方案. 解题分析 最多点的数量就是入度为偶数的点. 将入度为奇数的点每两个组成一队,连一条无向边,之后求出欧拉回路即可. 参考程序 1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath&

Codeforces 723e [图论][欧拉回路]

/* 不要低头,不要放弃,不要气馁,不要慌张. 题意: 给你一个有n个点,m条边的无向图,给每条边规定一个方向,使得这个图变成有向图,并且使得尽可能多的点入度与出度相同. 输出有多少个这样的点并且输出有向图. 思路: 1.针对每个连通分支. 2.所有点入度与出度相同,显然这是欧拉回路存在的判定定理,但是欧拉回路的另外一个等价定理是所有点的度数是偶数.那如果给我们的图中的某些点是奇数度该怎么办. 3.显然原图中给的点如果度数是奇数,那么该点的入度与出度一定不相同. 4.根据握手定理,无向图中度数是

[2016-04-01][codeforces][659E][New Reform]

时间:2016-04-01 19:27:59 星期五 题目编号:[2016-04-01][codeforces][659E][New Reform] 题目大意:给定n个城市,m条路,每条路连接两个城市,每两个城市最多只有一条路连接,现在把路改成单项的,问最少会出现几个孤立的城市(没有城市到达它), 分析: 在一个联通分支中,如果边数为n - 1,那么这个图就是树,树上除了根节点,其他节点都可达,如果边数大于n-1,那么至少会出现一个环,只要选的点在环上,那么所有的点都可达 题目不止一个联通分支,

CodeForces 659E New Reform

题意:给你一个无向图,如今要求你把边改成有向的. 使得入度为0的点最少,输出有多少个点入度为0 思路:脑补一波结论.假设有环的话显然没有点入度为0,其余则至少有一个点入度为0,然后就DFS一波就能够了 #include <cstdio> #include <queue> #include <cstring> #include <iostream> #include <cstdlib> #include <algorithm> #inc

CodeForces 659E New Reform (图的遍历判环)

Description Berland has n cities connected by m bidirectional roads. No road connects a city to itself, and each pair of cities is connected by no more than one road. It isnot guaranteed that you can get from any city to any other one, using only the

CodeForces 732F Tourist Reform

边双连通分量. 这题有一点构造的味道.一个有向图,经过强连通缩点之后会形成一个有向无环图. 如果将最大的强连通分量放在顶端,其余的强连通分量都直接或间接指向他,那么这样就构造出了符合要求的图. 接下来就是要去寻找强连通分量.对于一个无向图来说,每一个边-双联通分量都可以将每条边定向之后构造成一个强连通分量,$dfs$一遍即可. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #

Codeforces Round #375 (Div. 2)E. One-Way Reform

题目链接:传送门 题目大意:一副无向图,要求你给边定向(变为有向图),使出度等于入度的点最多,输出有多少 个点,并且输出定向后的边(前为起点,后为终点) 题目思路:欧拉路 我们这样考虑,先考虑无向图的点的度数,如果为奇数则一定无法变为题目要求的点,ans-1 对于度为偶数的点则一定可以通过调整满足. 处理方法:新建一个虚拟节点0,使所有度为奇数的点向其连一条边,那么最终图中的点的度数都为偶数. 这样就满足欧拉路的条件了.我们只需要跑欧拉路并且将走过的路径保留下来即可. 注意将与虚拟节点连的边删去

codeforces CF732F Tourist Reform Tarjan边双连通分量

$ \rightarrow $ 戳我进CF原题 一张有向图中,设 $ r_i $ 为从点 $ i $ 出发能够到达的点的数量. 定义有向图的"改良值"为 $ r_i $ 的最小值. 现给出一张无向图,要求给每条边定一个方向,使产生的有向图"改良值"最大. $ n,m \le 400000 $ 对于无向图的每个"边双连通分量",一定存在一种定向方法,使其改良值等于其大小 把无向图缩点后,以最大的 $ e-DCC $ 为零出度点(终点) $ BFS

Codeforces Round #346 (Div. 2) (659A,659B,659C,659D(几何叉乘),659E(并查集))

Round House 题目链接: http://codeforces.com/problemset/problem/659/A 解题思路: The answer for the problem is calculated with a formula ((a?-?1?+?b)  n + n)  n + 1. Such solution has complexity O(1). There is also a solution with iterations, modelling every o