CF 1325F - Ehab's Last Theorem
Posted scnucjh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 1325F - Ehab's Last Theorem相关的知识,希望对你有一定的参考价值。
首先:
无向图的dfs树无横边
这很显然,因为若有u->v 为横边,那么v早就从这条边过来找u了...矛盾
设 (k = ceil( sqrt{n} ))
接下来跑dfs树,如果有回边使得环大于等于k,就输出环。
否则,说明一个问题:所有点的回边的数量都小于k(不然一定能找到环了,鸽巢原理~)
于是,可以不停自底向上地选取点为独立集点,同时把它的领边都标记为不能取为独立集。
结果一定至少有k个独立集点。
为什么? 因为前面说了,所有点的回边的数量都小于k,这样取点,每去一次点,最多标记k-1个点为非独立集。
代码中,flag[i] = 1 表示(i)已经标为不是独立集点。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5;
bool flag[N];
int fa[N], dep[N];
int n,m,k;
vector<int> G[N];
void dfs(int x,int f,int d) {
dep[x] = d;
fa[x] = f;
for(auto y:G[x]) {
if(dep[y]==0)
dfs(y,x,d+1);
if(dep[x]-dep[y]+1>=k) {
cout<<2<<endl;
cout<<dep[x]-dep[y]+1<<endl;
cout<<y<<" ";
int z = x;
while(z!=y) {
cout<<z<<" ";
z = fa[z];
}
exit(0);
}
}
if(!flag[x])
for(auto y:G[x]) {
flag[y] = 1;
}
}
int main() {
ios::sync_with_stdio(0);
cin>>n>>m;
while(k*k<n) k++;
for(int i=0,a,b;i<m;i++) {
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
dfs(1,0,1);
cout<<1<<endl;
for(int i=1; k; i++) {
if(flag[i]) continue;
cout<<i<<" ";
k--;
}
return 0;
}
以上是关于CF 1325F - Ehab's Last Theorem的主要内容,如果未能解决你的问题,请参考以下文章
CF1364D Ehab‘s Last Corollary(思维,环,二分图,构造)
CF1364D Ehab‘s Last Corollary(思维,环,二分图,构造)
CF D. Ehab and the Expected XOR Problem 贪心+位运算
codeforces1364 D. Ehab's Last Corollary(最小环)
Codeforces Round #628 (Div. 2) F——Ehab's Last Theorem dfs
Codeforces Round #649 (Div. 2) D - Ehab's Last Corollary dfs