题目链接: 1003 Cover
题目大意
一张无向图,n个节点,m条边,没有重边和自环,不一定连通,求最少多少条路径能覆盖这张图所有边,每条边只能被一条路径覆盖
思路
将图中每个联通块的奇点(度数为奇数的点)找出来,如果有两个或两个以下的奇点,可以一笔画,否则从第三个奇点开始,将奇点们两两连接起来,让这张图有欧拉通路,求其欧拉通路,将后来新增的奇点连边删除后,得到的路径就是覆盖这个联通块所有边需要的最小路径数
代码
6311 1060MS 19164K 2465 B G++
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 1e5 + 100, mod = 1e9 + 7, inf = 0x3f3f3f3f;
typedef pair<int, int> P;
typedef long long ll;
int n, m;
struct edge
{
int to, nxt;
edge(int t = 0, int n = 0) : to(t), nxt(n) {}
};
edge es[maxn * 3];
int head[maxn * 3];
int d[maxn];
void addedge(int id, int u, int v)
{
es[id * 2] = edge(v, head[u]);
head[u] = id * 2;
es[id * 2 + 1] = edge(u, head[v]);
head[v] = id * 2 + 1;
}
vector<int> odd;
int cnt_path;
vector<int> path[maxn];
bool vist_node[maxn];
void find_odd(int u)
{
vist_node[u] = 1;
if (d[u] & 1) odd.push_back(u);
for (int i = head[u]; i; i = es[i].nxt)
{
int v = es[i].to;
if (vist_node[v]) continue;
find_odd(es[i].to);
}
}
bool vist_edge[maxn * 3];
void dfs(int u)
{
for (int i = head[u]; i; i = es[i].nxt)
{
int v = es[i].to;
if (vist_edge[i / 2]) continue;
vist_edge[i / 2] = 1;
dfs(v);//先dfs再记录路径, 遇到桥的时候即使先走了桥也能记录一条完整的路径
if (i / 2 > m) ++cnt_path;
else path[cnt_path].push_back(i / 2 * ((i & 1) ? 1 : -1));
}
}
int main()
{
while (scanf("%d%d", &n, &m) == 2)
{
int u, v;
memset(d, 0, sizeof(d));
memset(head, 0, sizeof(head));
memset(vist_node, 0, sizeof(vist_node));
memset(vist_edge, 0, sizeof(vist_edge));
for (int i = 1; i <= m; ++i)
{
scanf("%d%d", &u, &v);
addedge(i, u, v);
++d[u];
++d[v];
}
int id = m + 1;
for (int i = 1; i <= n; ++i)
{
if (!vist_node[i] && d[i])
{
find_odd(i);
if (odd.size() == 0) odd.push_back(i);
for (int j = 2; j < (int)odd.size(); j += 2) //
addedge(id++, odd[j], odd[j + 1]);
++cnt_path;
dfs(odd[0]);
odd.clear();
}
}
printf("%d\n", cnt_path);
for (int i = 1; i <= cnt_path; ++i)
{
printf("%d", (int)path[i].size());
for (int ite : path[i]) printf(" %d", ite);
printf("\n");
}
for (int i = 1; i <= cnt_path; ++i) path[i].clear();
cnt_path = 0;
}
return 0;
}