贪心思想 因为题目所求的二分图至少有m/2条边 所以对于每个点 只看其邻接点中位于那个集合的点多 这样当前点的邻接边至少有一半加入了所建立的二分图中 最终肯定满足m/2
注意 二分图未必连通
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int v;
int next;
};
node edge[30010];
int first[110],book[110];
int v1[110],v2[110];
int n,m,num,c1,c2;
void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
return;
}
void solve(int cur)
{
int i,v,cnt1,cnt2;
cnt1=0,cnt2=0;
for(i=first[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(book[v]==1) cnt2++;
if(book[v]==2) cnt1++;
}
if(cnt1>cnt2)
{
book[cur]=1;
v1[++c1]=cur;
}
else
{
book[cur]=2;
v2[++c2]=cur;
}
return;
}
int main()
{
int t,i,u,v;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(first,-1,sizeof(first));
memset(book,0,sizeof(book));
num=0;
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
c1=0,c2=0;
for(i=1;i<=n;i++)
{
solve(i);
}
printf("%d ",c1);
for(i=1;i<=c1;i++) printf("%d ",v1[i]);
printf("\n");
printf("%d ",c2);
for(i=1;i<=c2;i++) printf("%d ",v2[i]);
printf("\n");
}
return 0;
}