题目描述
题目大意
给出一个3n个点、m条边的无向图,找一个n条边的边集(保证没有重点)或n个点的点集(保证没有相邻点)
题解
这题的正解很妙
由于有3n个点,可知2n/2≥n和n≥n和n+2n=3n
废话
所以暴力找出一个尽可能大的边集,使得没有两个边集外的点相邻
显然,剩下的是一个合法的点集
如果找到≥n条边,那么就输出边集
否则边集覆盖的点<2n,则剩下点集的大小一定>n
code
#include <iostream>
#include <cstdlib>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
using namespace std;
bool bz[300001];
bool Bz[500001];
int T,n,m,i,j,k,l,tot,sum;
int main()
{
// freopen("CF1199E.in","r",stdin);
scanf("%d",&T);
for (;T;--T)
{
scanf("%d%d",&n,&m);
tot=0;
sum=0;
fo(i,1,m)
{
scanf("%d%d",&j,&k);
if (!bz[j] && !bz[k])
{
Bz[i]=1;
bz[j]=1;
bz[k]=1;
++tot;
}
}
if (tot>=n)
{
printf("Matching\n");
fo(i,1,m)
if (Bz[i])
{
printf("%d ",i);
++sum;
if (sum==n)
break;
}
}
else
{
printf("IndSet\n");
fo(i,1,n+n+n)
if (!bz[i])
{
printf("%d ",i);
++sum;
if (sum==n)
break;
}
}
printf("\n");
fo(i,1,n+n+n)
bz[i]=0;
fo(i,1,m)
Bz[i]=0;
}
}