杭电ACM2094——产生冠军~~拓扑排序

题目的意思,如题。很容易明白。

解决的方法就是拓扑排序,就可以很容易的解决了。

每输入一对选手,判断两个选手是否出现过,没有出现过,新建一个头结点,加入到邻接表中,更新结点的入度。

最后判断是否存在一个结点的入度为0,有,则Yes,否则No。

我用的是STL中的list容器来创建的邻接表。

下面的是 AC的代码:

#include <iostream>
#include <list>
#include <cstring>
using namespace std;

class data             //结点的结构体
{
public:
	int indegree;
	int point;
	char str[100];
};

list <data> List[2000];    //链表数组,存在多个人

int main()
{
	int n, i, j, k;
	char s1[100], s2[100];
	data temp;
	while(cin >> n && n)
	{
		for(i = 0; i < 2000; i++)  //清空各个链表
			List[i].clear();
		k = 0;
		for(i = 0; i < n; i++)
		{
			cin >> s1 >> s2;
			int flag = 0, tag = 0, a, b;
			a = b = -1;
			for(j = 0; j < k; j++)
			{
				if(strcmp(List[j].front().str, s1) == 0)        //判断第一个人是否出现过
				{
					a = j;                                //标记在链表数组的下标
					flag = 1;
				}
				if(strcmp(List[j].front().str, s2) == 0)          //判断第二个人是否出现过
				{
					b = j;                                 //同上
					tag = 1;;
				}
			}
			if(!flag)                //没存在,新建一个,扩大数组的大小
			{
				strcpy(temp.str, s1);
				temp.indegree = 0;
				temp.point = -1;
				List[k].insert(List[k].end(), temp);
				k++;
			}
			if(!tag)   //同上
			{
				strcpy(temp.str, s2);
				temp.indegree = 0;
				temp.point = -1;
				List[k].insert(List[k].end(), temp);
				k++;
			}
			if(flag && !tag)    //第一个出现过,第二个没有
			{
				List[k - 1].front().indegree++;   //更新入度
				strcpy(temp.str, s2);
				temp.indegree = -1;
				temp.point = k - 1;
				List[a].insert(List[a].end(), temp);
			}
			else if(!flag && tag)   //第一个没出现,第二个出现过
			{
				List[b].front().indegree++;
				strcpy(temp.str, s2);
				temp.indegree = -1;
				temp.point = b;
				List[k - 1].insert(List[k - 1].end(), temp);
			}
			else if(flag && tag)   //都出现过
			{
				List[b].front().indegree++;
				strcpy(temp.str, s2);
				temp.indegree = -1;
				temp.point = b;
				List[a].insert(List[a].end(), temp);
			}
			else if(!flag && !tag)  //都没出现过
			{
				List[k - 1].front().indegree++;
				strcpy(temp.str, s2);
				temp.indegree = -1;
				temp.point = k - 1;
				List[k - 2].insert(List[k - 2].end(), temp);
			}
		}
		int ans = 0;
		for(i = 0; i < k; i++)
		{
			if(List[i].front().indegree == 0 && !List[i].empty())
				ans++;
		}
		if(ans == 1)
			cout << "Yes" << endl;
		else
			cout << "No" << endl;
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值