1 条题解
-
0
自动搬运
来自洛谷,原作者为

devout
想要变得可爱qwq | AFO搬运于
2025-08-24 23:09:40,当前版本为作者最后更新于2025-05-13 14:40:51,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目描述
有一个图,问是否能删不超过两条边使得它变成一个二分图,如果不可以输出0,否则输出删除边数最少得方案数。
题目解答
发现这个图几乎是一个二分图,所以可以考虑先做一个二分图染色,得到了一棵 dfs 树,这棵树的非树边一定是返祖边。一条非树边可以和树边形成一个环,如果是奇环则称其为奇边,否则称其为偶边,显然如果没有奇边则直接输出 即可。
设 为所有奇边的集合对每条边 ,若 是一条非树边,则 ,否则设 ,定义 是所有 子树到 子树外的返祖边的集合。
若最少删一条边
如果删的是非树边 ,则删的一定是唯一的一条奇边。
如果删的是树边 ,显然 ,而如果 ,任取偶边 ,奇边 , 和若干条(偶数条)依然构成一个奇环。
综上,删一条边的情况等价于 。
若最少删两条边
设删去 两条边,设 。
显然 均非空,否则可以删一条边解决。
任取 , 和树边构成的奇环并没有因为 切断,因此 一定切断了这个奇环,这也就意味着对于 来说, 是跨过这条边的返祖边,即 ,同时如果 ,则这个奇环还是没有切断,因此 ,即 。
对 结论同样成立,因此 。 又显然任意 他至少在 之一里,所以可以删两条边的情况等价于:
s.t. 。
程序实现
发现维护集合是复杂度非常不合理的,可以考虑哈希,注意到我们只需要维护集合,并且需要实现集合的加减等操作,因此可以考虑异或哈希,给每条边随机权值 ,集合 的哈希值 。
mt19937_64 rnd(time(0)); int head[N],ecnt; int col[N],dep[N]; ull S,T[N]; bool vis[N]; map<ull,int> cnt; struct Edge{ int to,next; }e[N<<1]; void add(int x,int y){ e[++ecnt]=(Edge){y,head[x]},head[x]=ecnt; } void dfs(int u,int fa){ vis[u]=true; RepG(i,u){ int v=e[i].to; if(v==fa)continue; if(!vis[v]){ col[v]=col[u]^1; dep[v]=dep[u]+1; dfs(v,u); T[u]^=T[v]; } else if(dep[v]<dep[u]){ ull x=rnd(); T[u]^=x; T[v]^=x; if(col[u]==col[v])S^=x; cnt[x]++; } } cnt[T[u]]++; } long long count_ways(int n, std::vector<int> U, std::vector<int> V) { for(int i=0;i<U.size();i++)add(U[i],V[i]),add(V[i],U[i]); dfs(1,0); if(!S)return 1; else if(cnt[S])return cnt[S]; else{ ll res=0; for(auto [x,t]:cnt)res+=1ll*t*cnt[x^S]; return res/2; } }
- 1
信息
- ID
- 11375
- 时间
- 3000ms
- 内存
- 1024MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者