确定比赛名次(拓扑排序)HDU - 1285

题目:确定比赛名次

vjudge提交链接

题意:
——n支队伍,给出m行对战信息。
每行a,b表示a队赢了b队。
输出一个符合要求的队伍排名。
注意:若符合条件的排名不唯一,编号小的队伍在前。
注意:数据可能存在重复。
数据范围:n<=500。

题解:

  1. 若n的范围如题目所示,暴力+拓扑排序。
    注意事项:
    去重用sort排序或者二维数组标记都行。
    一次只排一个队伍的名次,不然会错的。
  2. 若n超过十万,sort排序+邻接表+优先队列+拓扑排序
    解释:
    sort排序:数据去重。
    邻接表:存队伍信息。
    优先队列:一次可多个队伍进队列,不会影响结果。

代码1:n比较小。

#include
#include
#include
using namespace std;
int du[550],e[550][550];
int n,m;
void tpsort()
{
	int cnt=0,flag=0;
	while(1)
	{
		for(int i=1;i<=n;i++)
		{
			if(du[i]==0)
			{
				if(flag)	printf(" ");
				flag=1;
				printf("%d",i);
				cnt++;
				if(cnt==n)	break;
				du[i]=-1;
				for(int j=1;j<=n;j++)
					if(e[i][j])	du[j]--;
				break;//一次只能排一个 
			}
		}
		if(cnt==n)	break;
	}
	printf("\n");
}
int main()
{
	while(~scanf("%d %d",&n,&m))
	{
		memset(du,0,sizeof(du));
		memset(e,0,sizeof(e));
		int a,b;
		for(int i=1;i<=m;i++)
		{
			scanf("%d %d",&a,&b);
			if(e[a][b])	continue;//去重 
			e[a][b]=1;
			du[b]++;
		}
		tpsort();
	}
	return 0;
}

代码2:n超过10万

#include
#include
#include
#include
#include
using namespace std;
const int M=250000;
vector vt[M];
int du[550];
int n,m;
struct Node{
	int a,b;
}q[M];
bool cmp(Node a,Node b){return a.a,greater > Q;
	for(int i=1;i<=n;i++)
		if(du[i]==0)	Q.push(i);
	int flag=0; 
	while(!Q.empty())
	{
		int a=Q.top();
		Q.pop();
		if(flag)	printf(" ");
		flag=1;
		printf("%d",a);
		for(int j=0;j

你可能感兴趣的:(STL,排序算法,算法)