给出一种方案使
n
n
n个点
m
m
m条边分成两部分,两部分之间的边数
≥
m
2
gefrac{m}{2}
≥2m。
n
≤
1
0
5
,
m
≤
2
∗
1
0
5
nle10^5,mle2*10^5
n≤105,m≤2∗105
题解
没用的边删去后,剩下的部分是一张二分图,考虑贪心染色。
DFS的过程中,每到一个未染色的点,统计与它相邻的点的颜色,将它自己染为较少的那种,令这些点有
s
s
s个,即边共
s
s
s条,这样可以保证连出的边
≥
s
2
gefrac{s}{2}
≥2s,那么最后连出的边
≥
m
2
gefrac{m}{2}
≥2m。
代码
#include<cstdio>#include<cstring>#include<algorithm>usingnamespace std;#define N 100010#define M 200010int last[N], nxt[M *2], to[M *2], len =1;int co[N], sum =0;voidadd(int x,int y){
to[++len]= y;
nxt[len]= last[x];
last[x]= len;}voiddfs(int k){int s0 =0, s1 =0;for(int i = last[k]; i; i = nxt[i]){
s0 +=(co[to[i]]==0), s1 +=(co[to[i]]==1);}
co[k]=(s1 <= s0);
sum +=min(s1, s0);for(int i = last[k]; i; i = nxt[i])if(co[to[i]]==-1)dfs(to[i]);}intmain(){int n, m, i, x, y;scanf("%d%d",&n,&m);for(i =1; i <= m; i++){scanf("%d%d",&x,&y);add(x, y),add(y, x);}memset(co,255,sizeof(co));for(i =1; i <= n; i++)if(co[i]==-1)dfs(i);for(i =1; i <= n; i++)printf("%d ", co[i]);return0;}