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\n", 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('\n');
                                }
                                else
                                {
                                        putchar(' ');
                                }
                        }
                }
        }
        return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Aragaki/p/9378585.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值