1. 程式人生 > 實用技巧 >CF1325F Ehab's Last Theorem(dfs樹找環與獨立集)

CF1325F Ehab's Last Theorem(dfs樹找環與獨立集)

對於圖建立dfs樹,這樣只存在樹邊和B邊,不會存在橫叉邊,這也是tarjan演算法的思想

建立dfs樹後,我們發現任意一條B邊都會生成一個環,且所有b邊就是所有環

我們進行dfs棧的建立,找到如果存在滿足條件的環,那就直接輸出

如果不存在,我們證明肯定存在滿足條件的獨立集。因為根據鴿巢定理,每個點一定不會有大於lim-2條回邊,這是因為一旦有lim-1條,則肯定能聯通lim個點,那麼就存在滿足條件的環

既然發現這個,我們就可以從深度最低的開始打tag,不斷往回,一定能找到答案。

#include<bits/stdc++.h>
using namespace std;
typedef 
long long ll; const int N=5e5+10; int h[N],ne[N],e[N],idx; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } int n,m,lim; stack<int> q; int depth[N]; int tag[N]; void dfs(int u,int now,int fa){ depth[u]=now; q.push(u); int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i];
if(j==fa) continue; if(!depth[j]){ dfs(j,now+1,u); } else{ if(depth[u]-depth[j]+1>=lim){ cout<<2<<endl; cout<<depth[u]-depth[j]+1<<endl; for(i=depth[u]-depth[j]+1;i>=1
;i--){ int t=q.top(); q.pop(); cout<<t<<" "; } cout<<endl; exit(0); } } } if(!tag[u]){ for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; tag[j]=1; } } q.pop(); } int main(){ int k; ios::sync_with_stdio(false); cin>>n>>m; memset(h,-1,sizeof h); lim=sqrt(n); if(lim*lim<n) lim++; while(m--){ int a,b; cin>>a>>b; add(a,b); add(b,a); } depth[1]=1; dfs(1,1,-1); cout<<1<<endl; int cnt=1; while(lim){ while(tag[cnt]) cnt++; cout<<cnt<<" "; cnt++; lim--; } return 0; }
View Code