中南多校对抗赛 第三场 E

E:Eulerian Flight Tour

题意:

给你一张无向图,要你给这个图加边使得其形成一个欧拉回路

题解:

首先使得所有节点的度都为偶数,然后将这个图联通起来

对于度为奇数的点,将将他和他的父节点连接起来

连接完后如果这个图是联通的,那么就直接输出结果

如果这个图有多个联通块:

分类讨论:

如果有2个联通块,两个联通块对着连成一个环

如果有多个联通块,用一个环将这几个联通块连起来即可

代码:

# E:Eulerian Flight Tour

## 题意:

给你一张无向图,要你给这个图加边使得其形成一个欧拉回路

## 题解:

首先使得所有节点的度都为偶数,然后将这个图联通起来

对于度为奇数的点,将将他和他的父节点连接起来

连接完后如果这个图是联通的,那么就直接输出结果

如果这个图有多个联通块:

分类讨论:

如果有2个联通块,两个联通块对着连成一个环

如果有多个联通块,用一个环将这几个联通块连起来即可

代码:

```c++
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
#define FIN freopen("input.txt","r",stdin);
const int maxn = 4e3 + 5;
int n, m;
int vis[maxn];
int deg[maxn];
bool G[maxn][maxn];
bool flag;
vector<pii> ans;
void dfs(int u, int p) {
    vis[u] = 1;
    for(int v = 1; v <=n; v++) {
        if(vis[v]) continue;
        if(G[u][v]) continue;
        dfs(v, u);
    }
    if(deg[u] & 1) {
        if(p == -1) flag = false;
        else {
            ans.push_back(make_pair(u, p));
            deg[u]++, deg[p]++;
            G[u][p] = G[p][u] = 1;
        }
    }
}

vector<int> tmp;
vector<vector<int>> A;
void dfs1(int u) {
    vis[u] = 1;
    for(int v = 1; v <= n; v++) {
        if(v == u) continue;
        if(vis[v]) continue;
        if(!G[u][v]) continue;
        dfs1(v);
    }
    tmp.push_back(u);
}
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    cin >> n >> m;
    memset(deg,0,sizeof(deg));
    memset(G,0,sizeof(G));
    for(int i = 0, u, v; i < m; i++) {
        cin >> u >> v;
//        u--,v--;
        deg[u]++, deg[v]++;
        G[u][v] = G[v][u] = 1;
    }
//    cout<<"hhh"<<endl;
    flag = true;
    ans.clear();
    for(int i = 1; i <= n; i++) {
        if(vis[i]) continue;
        dfs(i, -1);
    }
    if(!flag) {
        cout << -1 << endl;
    } else {
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i++) {
            if(vis[i]) continue;
            tmp.clear();
            dfs1(i);
            A.push_back(tmp);
        }
        if (A.size() == 2) {
            if (A[0].size() > A[1].size()) swap(A[0], A[1]);
            if (A[0].size() == 1) {
                int t = A[0][0];
                int u = -1, v=-1;
                for (int i = 0; i < A[1].size(); ++i) {
                    for(int j = i + 1; j < A[1].size(); ++j) {
                        int cu = A[1][i], cv = A[1][j];
                        if (!G[cu][cv]) u = cu, v = cv;
                    }
                }
                if (u == -1) {
                    if (ans.size() == 0) {
                        cout << -1 << endl;
                        return 0;
                    }
                    u = ans.back().first;
                    v = ans.back().second;
                    ans.pop_back();
                } else {
                    ans.push_back(make_pair(u, v));
                }
                ans.push_back(make_pair(t, u));
                ans.push_back(make_pair(t, v));
            } else {
                for (int it = 0; it < 2; ++it) {
                    for (int it2 = 0; it2 < 2; ++it2) {
                        ans.push_back(make_pair(A[0][it], A[1][it2]));
                    }
                }
            }
        } else if (A.size() > 2) {
            for (int i = 0; i < A.size(); ++i) {
                int j = (i + 1) % A.size();
                ans.push_back(make_pair(A[i][0], A[j][0]));
            }
        }
        cout << ans.size() << endl;
        for (int i = 0; i < ans.size(); i++) {
            if (ans[i].first > ans[i].second) swap(ans[i].first, ans[i].second);
            cout << ans[i].first << " " << ans[i].second  << endl;
        }
    }
    return 0;
}

```
View Code

 

猜你喜欢

转载自www.cnblogs.com/buerdepepeqi/p/10630195.html