标签:class exit 位置 back pre rem 语句 说明 amp
#include<bits/stdc++.h> #define ls rt<<1 #define rs rt<<1|1 using namespace std; typedef long long ll; const int p=1e8+7; vector<int>v[1001000],ans; int d[100010],vis[100100],nd; void dfs(int x,int fa) { ans.push_back(x); d[x]=ans.size();//x在ans中的位置 for(auto i:v[x]) { if(i==fa) continue; if(!d[i]) dfs(i,x);//如果没有遍历过,往下遍历 else if(d[x]-d[i]+1>=nd)//如果已经遍历过,说明是个环,判断环的大小 { printf("2\n%d\n",d[x]-d[i]+1);//环的大小 通过在ans中的编号搞出来 for(int j=d[i]-1; j<d[x]; j++) printf("%d ",ans[j]);//输出环,因为在vector种下标的缘故,整体要往左移动一个单位 printf("\n"); exit(0); } } //如果x没有遍历过 记得把和x相邻的 都标记,为了第一种答案 if(!vis[x]) { for(auto i:v[x]) vis[i]=1; } //相当于反向回溯,因为他要的独立集,是不相邻的,处理最后一个元素时,把和她相邻的都标记,然后把最后一个删掉,删掉的记作x,然后再往回 //如果此时最后的 和 x 相邻,那么已经被标记过,也就不能再执行上面的语句了,就直接被删掉 //这样不会出现重复被标记的问题 ans.pop_back(); } int main() { int n,m,x,y; scanf("%d%d",&n,&m); nd=sqrt(n); if(nd*nd<n) nd++; for(int i=1; i<=m; i++) { scanf("%d%d",&x,&y); v[x].push_back(y),v[y].push_back(x); } dfs(1,0); printf("1\n"); for(int i=1; i<=n&&nd; i++) if(!vis[i]) printf("%d ",i),nd--; }
Codeforces Round #628 (Div. 2) F——Ehab's Last Theorem dfs
标签:class exit 位置 back pre rem 语句 说明 amp
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/13124183.html