zoukankan      html  css  js  c++  java
  • Cow Contest (POJ

    FJ的N(1 <= N <= 100)头奶牛们最近参加了场程序设计竞赛:)。在赛场上,奶牛们按1…N依次编号。每头奶牛的编程能力不尽相同,并且没有哪两头奶牛的水平不相上下,也就是说,奶牛们的编程能力有明确的排名。 整个比赛被分成了若干轮,每一轮是两头指定编号的奶牛的对决。如果编号为A的奶牛的编程能力强于编号为B的奶牛(1 <= A <= N; 1 <= B <= N; A != B) ,那么她们的对决中,编号为A的奶牛总是能胜出。 FJ想知道奶牛们编程能力的具体排名,于是他找来了奶牛们所有 M(1 <= M <= 4,500)轮比赛的结果,希望你能根据这些信息,推断出尽可能多的奶牛的编程能力排名。比赛结果保证不会自相矛盾。

    Input
    第1行: 2个用空格隔开的整数:N 和 M 第2…M+1行: 每行为2个用空格隔开的整数A、B,描述了参加某一轮比赛的奶 牛的编号,以及结果(编号为A,即为每行的第一个数的奶牛为 胜者)

    Output
    第1行: 输出1个整数,表示排名可以确定的奶牛的数目

    Sample Input
    5 5
    4 3
    4 2
    3 2
    1 2
    2 5

    Sample Output
    2

    思路:如果一头牛比它大的牛的数量与比它小的牛的数量和等于n-1,那么这头牛的排名就可以确定。
    两种实现方式:
    (1) 先正向建图,然后dfs求比它小的数量,再反向建图,dfs求比它大的数量。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<queue> 
    #include<vector>
    typedef long long ll;
    #define pii pair<int,int> 
    using namespace std;
    const int N=10010,inf=0x3f3f3f3f;
    int T,n,m,k,dist1[N],dist2[N],num[N];
    int h[N],e[N],ne[N],idx;
    int l[N],r[N];
    bool st[510];
    void add(int a,int b)
    {
    	e[idx]=b;
    	ne[idx]=h[a];
    	h[a]=idx++;
    }
    int dfs(int u)//不是一棵树不能记忆化
    {
    	st[u]=1;//标记已经找过得点
    	int cnt=0;
    	for(int i=h[u];i!=-1;i=ne[i])
    	{
    		if(!st[e[i]])
    			cnt+=dfs(e[i]);
    	}
    	return cnt+1;
    }
    int main()
    {
    	memset(h,-1,sizeof h);
    	memset(dist1,-1,sizeof dist1);
    	memset(dist2,-1,sizeof dist2);
    	cin>>n>>m;
    	for(int i=1;i<=m;i++)
    	{
    		int a,b;
    		cin>>a>>b;
    		l[i]=a,r[i]=b;
    		add(a,b);
    	}
    	for(int i=1;i<=n;i++)
    		{
    			memset(st,0,sizeof st);//记得清空
    			dist1[i]=dfs(i);
    		}
    	idx=0;
    	memset(h,-1,sizeof h);//反向建图
    	for(int i=1;i<=m;i++)
    		add(r[i],l[i]);
    	for(int i=1;i<=n;i++)
    		{
    			memset(st,0,sizeof st);
    			dist2[i]=dfs(i);
    		}
    	int ans=0;
    	for(int i=1;i<=n;i++)
    		if(dist1[i]+dist2[i]==n+1)//两次dfs都包括了自身节点,所以就是n+1了
    			ans++;
    	cout<<ans;
    	return 0;
    }
    

    (2)弗洛伊德算法,d[i][j]==1表示i比j大,d[i][j]==0的话不确定。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<queue> 
    #include<vector>
    typedef long long ll;
    #define pii pair<int,int> 
    using namespace std;
    const int N=10010,inf=0x3f3f3f3f;
    int n,m,d[N][N];
    int sum[N],suf[N];//sum[i]比i大的数量,suf[i]比i小的数量
    int main()
    {
    	cin>>n>>m;
    	while(m--)
    	{
    		int a,b;
    		cin>>a>>b;
    		d[a][b]=1;
    	}
    	for(int k=1;k<=n;k++)
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=n;j++)
    				if(d[i][k]&&d[k][j])
    					d[i][j]=1;
    	int ans=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			sum[i]+=d[j][i];
    			suf[i]+=d[i][j];
    		}
    		if(sum[i]+suf[i]==n-1) ans++;
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    modelsim(2)
    【管理心得之十六】我来吐槽 “面试”
    【管理心得之十五】没有100%的答案,只有70%认可的答案
    【管理心得之十四】团队中的“短板”,是你?还是他?
    【管理心得之十三】真正步入轨道的管理,是单调无味的、是枯燥死板的
    【管理心得之十二】拿什么来拯救你我的“协力人员” (后篇)
    【管理心得之十一】拿什么来拯救你我的“协力人员” (前篇)
    【管理心得之十】你是信息的发送方,应尽的责任你做到了吗?
    【管理心得之九】奉劝那些把组织“玩弄于鼓掌之间”的OL们。(别让组织看见此篇)
    【管理心得之八】通过现象看本质,小王和小张谁更胜任?
  • 原文地址:https://www.cnblogs.com/neflibata/p/12871744.html
Copyright © 2011-2022 走看看