codeforces1199E

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目大意

给出一个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;
	}
}

猜你喜欢

转载自blog.csdn.net/gmh77/article/details/98324992