题目链接:http://codeforces.com/contest/1133/problem/F1
题意:一个无向图,你可以删去一些边得到一棵树,要求树中某个节点的度最大。
解题心得:
- 找到一个最大度的点,然后将他的儿子节点标记,然后从子节点开始dfs。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 100;
int n, m, degree[maxn];//记录节点数、边数、每个节点的度数
vector <int> ve[maxn];//记录图
vector <pair<int, int> > ans;//记录目标树的边
bool vis[maxn];
int init() {
int root = -1, Max = -1;
scanf("%d%d", &n, &m);
for(int i=0;i<m;i++) {
int u, v;
scanf("%d%d",&u, &v);
ve[u].push_back(v);
ve[v].push_back(u);
degree[u]++;
degree[v]++;
if(degree[u] > Max) {
Max = degree[u];
root = u;
}
if(degree[v] > Max) {
Max = degree[v];
root = v;
}
}
return root;
}
void dfs(int pre, int now) {
if(pre != -1) ans.push_back(make_pair(pre, now));
vis[now] = true;
for(int i=0;i<ve[now].size();i++) {
if(!vis[ve[now][i]]) dfs(now, ve[now][i]);
}
}
int main() {
// freopen("1.in", "r", stdin);
int root = init();
vis[root] = true;
for(int i=0;i<ve[root].size();i++) {
ans.push_back(make_pair(root, ve[root][i]));
vis[ve[root][i]] = true;
}
for(int i=0;i<ve[root].size();i++) {
dfs(-1, ve[root][i]);
}
for(int i=0;i<ans.size();i++) {
printf("%d %d\n", ans[i].first, ans[i].second);
}
return 0;
}