codeforces1364 D. Ehab's Last Corollary(最小环)
Posted fzuzyz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces1364 D. Ehab's Last Corollary(最小环)相关的知识,希望对你有一定的参考价值。
传送门:https://codeforces.com/contest/1364/problem/D
题目大意:给你个$n$个点,$m$条边的无向图,和一个$k$,找到以下一组条件:
(1)能找到$⌈frac{k}{2}⌉$个相互独立的点(两两之间没有边)
(2)找到一个小于等于$k$的环
存在性证明:
我们假设最小的环大小为$r$,如果$rleq k$,条件二成立,直接输出环即可。对于在环$r$上的任意两个不相邻的点$a,b$,假设$a,b$在环$r$上的距离分别为,$d_1,d_2$, 则有$d_1+d_2=r$,如果$a,b$之间有边,则会构成两个环长为$d_1+1$,$d_2+1$的环,由于$d_1+d_2=r$,$a$与$b$点不相邻,所以$d1,d2geq 2$,进而可以得到$d_1+1,d_2+1<r$,与r为最小环矛盾,所以在环r上的任意不相邻两点之间没有边,所以直接取最小环$r$上的隔项点即可,因为r>k,所以$⌊frac{r}{2}⌋ geq ⌈frac{k}{2}⌉$。
对于最小环的求解,采用dfs树,即dfs建树,即可求出。比赛时发现是CF1325F改编,只是把两个条件的数值作了简单的修改,出题人都是同一人,题目出的有一点摸鱼。最后现场学了最小环,取自https://blog.csdn.net/iamhpp/article/details/104951534
最后贴上AC代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair <ll,ll> pii; #define rep(i,x,y) for(int i=x;i<y;i++) #define rept(i,x,y) for(int i=x;i<=y;i++) #define per(i,x,y) for(int i=x;i>=y;i--) #define all(x) x.begin(),x.end() #define pb push_back #define fi first #define se second #define mes(a,b) memset(a,b,sizeof a) #define mp make_pair #define dd(x) cout<<#x<<"="<<x<<" " #define de(x) cout<<#x<<"="<<x<<" " #define debug() cout<<"I love Miyamizu Mitsuha forever. " const int inf=0x3f3f3f3f; const int maxn=2e5+5; vector<int> v[maxn]; bool vis[maxn]; int deep[maxn],f[maxn]; int n,m,k; int min_round=inf,p=0; void dfs(int id,int fa,int d) { deep[id]=d; vis[id]=1; f[id]=fa; rep(i,0,v[id].size()) { if(v[id][i]==fa) continue; if(vis[v[id][i]]) { if(abs(deep[v[id][i]]-deep[id])+1<=k) { cout<<2<<" "; int pos=id; int len=abs(deep[v[id][i]]-deep[id])+1; cout<<len<<" "; rep(i,0,len) { cout<<pos<<" "; pos=f[pos]; } exit(0); } else { if(min_round>abs(deep[v[id][i]]-deep[id])+1) { min_round=abs(deep[v[id][i]]-deep[id])+1; p=id; } } } else { dfs(v[id][i],id,d+1); } } } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m>>k; rep(i,0,m) { int a,b; cin>>a>>b; v[a].pb(b); v[b].pb(a); } dfs(1,-1,1); if(m==n-1) { vector<int> v1,v2; rept(i,1,n) if(deep[i]&1) v1.pb(i); else v2.pb(i); cout<<1<<" "; if(v1.size()<v2.size()) swap(v1,v2); int cnt=(k+1)/2; rep(i,0,cnt) cout<<v1[i]<<" "; cout<<" "; return 0; } cout<<"1 "; int cnt=(k+1)/2; for(;cnt;cnt--) { cout<<p<<" "; p=f[p]; p=f[p]; } cout<<‘ ‘; return 0; }
以上是关于codeforces1364 D. Ehab's Last Corollary(最小环)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #628 (Div. 2) D. Ehab the Xorcist(异或,思维题)
Codeforces Round #435 (Div. 2) D. Mahmoud and Ehab and the binary string[二分]
二进制构造Codeforces Round #628 (Div. 2) D. Ehab the Xorcist
Codeforces Round #649 (Div. 2) C. Ehab and Prefix MEXs