題目描述
題目大意
給出一個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;
}
}