题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2935
考察欧拉回路性质的题目呢;
TJ:https://blog.csdn.net/u014609452/article/details/53705451
首先按照题目给出的点对连边,发现能一连串输出的数组成一条路径;
那么答案就是图的最小路径覆盖的点数,可以考虑欧拉回路;
连通块之间分别考虑,如果连通块存在欧拉回路,那么覆盖它需要边数+1的点;
如果不存在欧拉回路,那么加上 度数绝对值和/2 条边构成欧拉回路,然后再任意删去一条,形成欧拉路,答案就是边数;
找连通块用并查集即可。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const maxn=1005; int n=1000,m,k,sum,ans,fa[maxn],deg[maxn]; bool vis[maxn],tag[maxn]; int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} int main() { scanf("%d",&m); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1,x,y;i<=m;i++) { scanf("%d%d",&x,&y); deg[x]++; deg[y]--; vis[x]=1; vis[y]=1; fa[find(x)]=find(y); } for(int i=1;i<=n;i++) if(vis[i]&°[i])tag[find(i)]=1,sum+=(deg[i]>0)?deg[i]:-deg[i]; for(int i=1;i<=n;i++) if(vis[i]&&find(i)==i&&!tag[i])k++;//此连通块没有度数非0的点,也就是存在欧拉回路,+1 ans=k+sum/2+m; printf("%d",ans); return 0; }