zoukankan      html  css  js  c++  java
  • Euler-path

    对于每个连通块欧拉回路存在的条件

    无向图:只存在两个或者零个度数为奇数的点

    有向图:每个点的入度等于出度或者至多有两个点入度不等于出度且一个出度比入度多一另一个入度比出度多一

    HDU 多校第二场 C.cover

    题意:给你一个无向图 问你一笔画最多多少次能把所有边覆盖(走过的边不能走)

    并且输出每个一笔画的路径(边的下标)

    解:给每一对度数为奇数的点连上一条边使之度数变成偶数 然后跑欧拉回路

    欧拉回路是从一个正确的点出发然后暴力dfs遇到走过的边就不要走

    /*Huyyt*/
    #include<bits/stdc++.h>
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const double eps = 1e-9;
    const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}};
    const int mod = 1e9 + 7, gakki = 5 + 2 + 1 + 19880611 + 1e9;
    const int MAXN = 1e5 + 5, MAXM = 2e5 + 5, MAXQ = 200010, INF = 1e9;
    const ll LLINF = (1LL << 50);
    int to[MAXM << 1], nxt[MAXM << 1], Head[MAXN], tot = 1;
    int index[MAXM << 1];
    bool used[MAXM << 1];
    inline void addedge(int u, int v, int x)
    {
            if (u == v)
            {
                    return ;
            }
            to[++tot] = v;
            nxt[tot] = Head[u];
            index[tot] = x;
            used[tot] = false;
            Head[u] = tot;
    }
    inline void read(int &v)
    {
            v = 0;
            char c = 0;
            int p = 1;
            while (c < '0' || c > '9')
            {
                    if (c == '-')
                    {
                            p = -1;
                    }
                    c = getchar();
            }
            while (c >= '0' && c <= '9')
            {
                    v = (v << 3) + (v << 1) + c - '0';
                    c = getchar();
            }
            v *= p;
    }
    int n, m;
    int du[100005];
    bool visit[100005];
    int ans = 0;
    vector<int> anser[100005];
    int cnt = 0;
    void dfs(int x)
    {
            int nowindex;
            visit[x] = true;
            for (int v, i = Head[x]; i; i = nxt[i])
            {
                    v = to[i];
                    if (used[i])
                    {
                            continue;
                    }
                    used[i] = used[i ^ 1] = true;
                    nowindex = index[i];
                    //cout << x << " to " << v << " index " << nowindex << " i " << i << endl;
                    dfs(v);
                    if (nowindex == 0)
                    {
                            anser[++cnt].clear();
                    }
                    else
                    {
                            anser[cnt].push_back(-nowindex);
                    }
            }
    }
    int main()
    {
            ios_base::sync_with_stdio(0);
            cin.tie(0);
    
            int u, v;
            while (~scanf("%d %d", &n, &m))
            {
                    cnt = 0;
                    tot = 1;
                    for (int i = 1; i <= n; i++)
                    {
                            du[i] = 0;
                            visit[i] = false;
                            Head[i] = 0;
                    }
                    for (int i = 1; i <= m; i++)
                    {
                            read(u), read(v);
                            addedge(u, v, i);
                            addedge(v, u, -i);
                            du[u]++, du[v]++;
                    }
                    int aim = 0;
                    for (int i = 1; i <= n; i++)
                    {
                            if (du[i] & 1)
                            {
                                    if (aim)
                                    {
                                            addedge(aim, i, 0);
                                            addedge(i, aim, 0);
                                            aim = 0;
                                    }
                                    else
                                    {
                                            aim = i;
                                    }
                            }
                    }
                    for (int i = 1; i <= n; i++)
                    {
                            if (!visit[i] && (du[i] & 1))
                            {
                                    anser[++cnt].clear();
                                    dfs(i);
                                    cnt--;
                            }
                    }
                    for (int i = 1; i <= n; i++)
                    {
                            if (!visit[i] && du[i])
                            {
                                    anser[++cnt].clear();
                                    dfs(i);
                            }
                    }
                    printf("%d
    ", cnt);
                    for (int i = 1; i <= cnt; i++)
                    {
                            printf("%d ", anser[i].size());
                            for (int j = 0; j < anser[i].size(); j++)
                            {
                                    printf("%d", anser[i][j]);
                                    if (j == anser[i].size() - 1)
                                    {
                                            putchar('
    ');
                                    }
                                    else
                                    {
                                            putchar(' ');
                                    }
                            }
                    }
            }
            return 0;
    }
    View Code
  • 相关阅读:
    四则运算
    读书计划
    典型用户和场景分析
    课堂练习--电梯调度
    重力解锁--用户需求调研
    书籍促销活动优惠问题
    小组开发项目--NABC分析
    梦断代码读后感之终结篇
    结对开发-求环状二维数组最大子数组
    结对开发之大数溢出
  • 原文地址:https://www.cnblogs.com/Aragaki/p/9378585.html
Copyright © 2011-2022 走看看