http://codeforces.com/contest/1176/problem/E
题意:
n
个
点
m
条
边
组
成
的
无
自
环
图
,
要
求
选
出
不
超
过
⌊
n
/
2
⌋
个
点
,
使
得
图
中
剩
余
的
其
他
点
都
与
选
出
的
点
有
边
相
连
,
输
出
这
些
点
n个点m条边组成的无自环图,要求选出不超过⌊n/2⌋个点,使得图中剩余的其他点都与选出的点有边相连,输出这些点
n个点m条边组成的无自环图,要求选出不超过⌊n/2⌋个点,使得图中剩余的其他点都与选出的点有边相连,输出这些点
题解:
读
懂
题
目
就
知
道
这
是
个
最
小
支
配
集
的
裸
题
,
直
接
上
模
板
读懂题目就知道这是个最小支配集的裸题,直接上模板
读懂题目就知道这是个最小支配集的裸题,直接上模板
这题卡memset 赛后叉了一大片。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
int pre[maxn];
bool visit[maxn];
int newpos[maxn*3];
int now;
int n, m;
int tot;
int head[maxn];
struct Node {int to; int next;};
Node edge[maxn*3];
void add(int u,int v){
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void DFS(int x) {
newpos[now ++] = x;
for(int k = head[x]; k != -1; k = edge[k].next) {
if(!visit[ edge[k].to ]) {
visit[ edge[k].to ] = true;
pre[edge[k].to] = x;
DFS(edge[k].to);
}
}
}
bool s[maxn],st[maxn];
int MDS() {
int ans = 0;
for(int i = n - 1; i >= 0; i--) {
int t = newpos[i];
if(!s[t]) {
if(! st[ pre[t] ]) {
st[ pre[t] ] = true;
ans ++;
}
s[t] = true;
s[ pre[t] ] = true;
s[ pre[ pre[t] ] ] = true;
}
}
int cnt = 0;
printf("%d\n",ans);
for(int i = 1; i <= n; i++){
if(st[i]){
cnt++;
if(cnt > n/2) break;
printf("%d ",i);
}
}
puts("");
}
int main() {
int T;
cin>>T;
while(T--){
tot = 0;
cin>>n>>m;
int u,v;
for(int i = 0; i <= n; i++)
head[i] = -1;
for(int i = 0; i <= n; i++)
visit[i] = false;
for(int i = 0; i <= n; i++)
s[i] = false;
for(int i = 0; i <= n; i++)
st[i] = false;
while(m--){
cin>>u>>v;
add(u,v);
add(v,u);
}
now = 0;
visit[1] = true;
pre[1] = 1;
DFS(1);
MDS();
}
return 0;
}