E. Moment of Bloom
分析:
-
重构树 + + + 链上结论
结论:若考虑在树上,去掉所有奇数边的次数为 s u m / 2 sum/2 sum/2(sum为奇数点的个数)
对于一棵树来说,选取两个端点,这条链是唯一的
每次操作就能去掉两个奇数点,因次 s u m sum sum 还要除以二
-
然后用并查集在图上跑一遍生成树,再遍历每一条链即可
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int f[N];
int gf(int k) { return f[k]==k ? k : f[k]=gf(f[k]); }
vector <int> g[N];
int tot,re[N];
void dfs(int u,int v,int pre)
{
re[++tot]=u;
if(u==v)
{
printf("%d\n",tot);
for(int i=1;i<=tot;i++) printf("%d ",re[i]);
printf("\n");
}
for(int to : g[u]) if(to!=pre) dfs(to,v,u);
tot--;
}
int st[N],en[N],b[N];
signed main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
int x=gf(u),y=gf(v);
if(x!=y)
{
f[y]=x;
g[u].push_back(v);
g[v].push_back(u);
}
}
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&st[i],&en[i]);
b[st[i]]++; b[en[i]]++;
}
int ans=0;
for(int i=1;i<=n;i++) if(b[i]&1) ans++;
if(ans) return printf("NO\n%d\n",ans/2), 0;
puts("YES");
for(int i=1;i<=q;i++) dfs(st[i],en[i],0);
}