现在的位置: 首页 > 综合 > 正文

NYOJ20——吝啬的国度(BFS)

2017年11月21日 ⁄ 综合 ⁄ 共 1319字 ⁄ 字号 评论关闭

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=20

题目分析:其实上就是对输入的节点,建立一张图。由于这里的节点数比较大,所以不可能用二维的数组来保存邻接矩阵,这里用链表来描述邻接边。也就是说如果节点s,e相邻,那么在edge[e]后面加入终点为s的边,同样在edge[s]后面加入终点为e的边。然后采用广度优先遍历,因为第一次通过某个节点s访问到节点e,则节点s一定是节点e必然会通过的边。

参考代码:

#include<stdio.h>
#include<malloc.h>
#include<string.h>

typedef struct Node
{
	int e;
	Node *next;
};

Node edge[100001];
int flag[100001];
int queue[100001];

int AddEdge(Node *edge, int s, int e)//把连接s,e的边加到对应的边链表中
{
	Node *p = (Node *)malloc(sizeof(Node *));
	if(!p)
		return 1;
	p->e = e;
	p->next = edge[s].next;
	edge[s].next = p;

	p = (Node *)malloc(sizeof(Node *));
	if(!p)
		return 1;
	p->e = s;
	p->next = edge[e].next;
	edge[e].next = p;
	return 0;
}

void Destory(Node *edge, int n)//销毁边的链表
{
	Node *p;
	for(int i = 1; i <= n; ++i)
	{
		p = edge[i].next;
		while(p)
		{
			edge[i].next = p->next;
			free(p);
			p = edge[i].next;
		}
	}
}

int main()
{
	int a,b;
	int n,s;
	int i,t;
	int head,tail;
	Node *p;

	scanf("%d", &t);
	while(t--)
	{
		scanf("%d %d",&n,&s);

		memset(flag,0,sizeof(flag));
		memset(edge,0,sizeof(edge));

		for(i = 1; i < n; ++i)
		{
			scanf("%d %d",&a, &b);
			if(AddEdge(edge, a, b))
				break;
		}
		
		queue[0] = s;
		head = 0;
		tail = 1;
		flag[s] = 1;
		while(head <= tail)
		{
			p = edge[queue[head]].next;
			while(p)
			{
				//如果该点没有访问过,设访问标记,加入队列
				if(!flag[p->e])
				{
					queue[++tail] = p->e;
					flag[p->e] = queue[head];
				}
				p = p->next;
			}
			++head;
		}

		flag[s] = 0;
		for(i = 1; i < n; ++i)
		{
			if(flag[i])
				printf("%d ",flag[i]);
			else//如果某些节点时孤立点,那么直接输出-1
				printf("-1 ");
		}
		if(flag[i])
			printf("%d\n",flag[i]);
		else
			printf("-1\n");
	}
	Destory(edge,n);
}

抱歉!评论已关闭.