ACM足球赛

NKUACM最近要举行足球赛,作为此次赛事的负责人,Lee要对报名人员进行分队。分队要遵循如下原则:

  1. 一个人不能加入多支队伍;
  2. 不认识的人不能分在同一队;
  3. 如果ab认识,bc认识,那么认为ac也认识;
  4. 每支队伍上限8人,下限5人;
  5. 尽量使队伍满员。

由于参赛人数很多,Lee表示无能为力,所以请你帮助Lee编程解决比赛有多少队伍。

Input

第一行输入两个整数,nmn(1<=n<=300000)代表报名人数,m(1<=m<=500000)代表关系数。接下来m行每行两个整数a(1<=a<=n)b(1<=b<=n)表示ab认识。

Output

输出一行,包含一个整数,表示队伍数量。

Sample Input

11 10

1 2

2 3

2 6

3 4

4 5

5 6

7 9

9 11

11 8

8 10

Sample Output

2

//使用邻接表存储图
//深度优先遍历的典型示例
#include<stdio.h>
#include<stdlib.h>

#define status int
#define YES 0
#define NO  1
#define OK 0
#define ERROR 1
#define MAX_VEX 300

int visited[MAX_VEX];//标示是否被访问过

typedef struct ArcNode//边界点的结构类型
{
	int adjvex;
	struct ArcNode *next;
}ArcNode;
typedef struct VexNode//临界表的表头结构
{
	int vex;
	ArcNode *link;
}VexNode,AdjList[MAX_VEX];
typedef struct Graph//图的结构类型
{
	AdjList list;
	int vexnum,arcnum;
}Graph;

status creatGraph(Graph &G);//创建邻接表
int DFSTravers(Graph G);//深度优先遍历,作必要的处理,队伍个数的确定,返回队伍的个数
int DFS(Graph G,int v);//深度优先遍历返回此次遍历强连通分量的结点个数

int main()
{
	Graph G;
	if(creatGraph(G)==OK)
		printf("%d\n",DFSTravers(G));
	system("pause");
	return 0;
}
status creatGraph(Graph &G)
{
	int i,j,k;
	ArcNode *p,*q;
	p=q=NULL;
	scanf("%d %d",&G.vexnum,&G.arcnum);
	if(G.vexnum<1||G.vexnum>300000||G.arcnum<1||G.arcnum>500000)
	{
		printf("数字超出范围");
		return ERROR;
	}
	for(i=0;i<=G.vexnum;i++)
	{
		G.list[i].vex=i;
		G.list[i].link=NULL;
	}
	for(k=0;k<G.arcnum;k++)
	{
		p=q=NULL;
		scanf("%d %d",&i,&j);
		if(i<1||i>G.vexnum||j<1||j>G.vexnum)
		{
			printf("数字超出范围");
			return ERROR;
		} 
		p=G.list[i].link;
		while(p!=NULL)
		{
			q=p;//q此时被保存为p的前驱
			p=p->next;
		}
		p=q;

		q=(ArcNode *)malloc(sizeof(ArcNode));
		q->adjvex=j;
		q->next=NULL;

		if(p!=NULL)
			p->next=q;
		if(G.list[i].link==NULL)
			G.list[i].link=q;
	}
	return OK;
}
int DFSTravers(Graph G)
{
	int v,w;
	int sum_people;
	int sum_team;
	sum_people=0;
	sum_team=0;
	for(v=0;v<=G.vexnum;v++)
		visited[v]=NO;
	for(v=1;v<=G.vexnum;v++)//编号从1开始
	{
		sum_people=0;
		if(visited[v]==NO)
			sum_people=DFS(G,v);
		if(sum_people>=5)//下限为5
		{
			sum_team+=sum_people/8;
			if(sum_people%8>=5)
				sum_team++;
		}
	}
	return sum_team;
}
int DFS(Graph G,int v)
{
	int count;//作为返回值,记录此次遍历强连通分量的结点个数
	ArcNode *p;//作为临时变量,遍历以v为头的所有链接点
	count=0;
	visited[v]=YES;
	count++;
	for(p=G.list[v].link;p!=NULL;p=p->next)
		if(visited[p->adjvex]==NO)
		{
			count+=DFS(G,p->adjvex);
		}
	return count;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值