ural-1077. travelling tours

题意:

给定一 n 个节点 m 条边的图,求出来环的个数最大,且每个环点的个数大于2,环 i 与其他 T-1 个环
至少有一条边不一样。


分析:

n 个点 m 条边 p 个联通分量的图含有的环的个数是 m-n+p。先 dfs 求出来联通分量的个数,然后递归
输出即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
const int N=205;
vector<int> g[N];
int n,m;
int stack[N],lev[N];
bool vis[N];
int top;
void dfs(int u) {
if(vis[u]) return;
vis[u]=1;
for(int i=0;i<(int)g[u].size();i++) {
int v=g[u][i];
dfs(v);
}
}
void print(int u) {
stack[++top]=u;
lev[u]=top;vis[u]=1;
for(int i=0;i<(int)g[u].size();i++) {
int v=g[u][i];
if(!vis[v]) print(v);
else {
if(lev[u]-lev[v]>1) {
cout<<lev[u]-lev[v]+1;
for(int i=lev[v];i<=lev[u];i++) {
cout<<' '<<stack[i];
}
cout<<endl;
}
}
}
top--;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
cin>>n>>m;
for(int i=0;i<m;i++) {
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
int tmp=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) {
if(!vis[i]) dfs(i),tmp++;
}
cout<<m-n+tmp<<endl;
memset(vis,0,sizeof(vis));
top=0;
for(int i=1;i<=n;i++) {
if(!vis[i]) print(i);
}
return 0;
}