高校排名

【题目描述】

众所周知,大学里有许多不同的专业,但冗杂的专业造成了一个严重的问题:究竟哪个大学更好?

现提出一个新概念,使得此问题能够部分解决。举一个例子:

假设有三所大学:X大学、Y大学、Z大学,每所大学都有三个专业:A、B、C,而这三所大学三个专业的公认排名如下:

(1)A专业排名:X > Y > Z;

(2)B专业排名:X > Z > Y;

(3)C专业排名:Z > X > Y;

显然,X大学所有的专业比Y大学的排名都要靠前,所以X大学一定比Y大学好,运用新概念,我们就能够部分比较出一些大学的优劣。

给定一份完整的各所大学不同专业排名,需要找出K所大学(U1、U2、U3、······、Uk),Ui大学一定比Uj大学(i < j)好,询问K的最大值是多少。

【输入描述】

第一行输入两个整数N、M(0 < N,M ≤ 100),表示大学数目和专业数目;

接下来M行,每行输入N所大学的编号Uj,表示对于第i个专业,N所大学的排名。

【输出描述】

输出一个数,表示答案。

【样例输入】

3 3

1 2 3

1 3 2

3 1 2

【样例输出】

2

源代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int m,n,Num(0),Ans(0),f[101],In[101],Head[101],i[101][101];
struct Node
{
    int To,Next;
}Edge[10001];
void Add(int t1,int t2) //边表。
{
    Edge[++Num].To=t2;
    Edge[Num].Next=Head[t1];
    Head[t1]=Num;
}
int DFS(int t) //树形DP找最长链。
{
    if (!Head[t]) //孤独。
      return 1;
    if (f[t]!=-1) //链链衔接,一个重要的剪枝。
      return f[t];
    for (int a=Head[t];a;a=Edge[a].Next)
      f[t]=max(f[t],DFS(Edge[a].To)+1);
    return f[t]; //f[t]表示该节点最长链的长度。
}
int main() //其实去掉那些琐碎的东西,得到的就是核心问题。
{
    memset(f,-1,sizeof(f));
    scanf("%d%d",&n,&m);
    for (int a=1;a<=m;a++)
      for (int b=1;b<=n;b++)
      {
        int t;
        scanf("%d",&t);
        i[t][a]=b; //i[a][b]表示在第a个专业方面,第b所大学的排名。
      }
    for (int a=1;a<=n;a++)
      for (int b=1;b<=n;b++) //纯枚举。
        if (a!=b)
        {
            bool Flag(0);
            for (int c=1;c<=m;c++)
              if (i[a][c]>i[b][c])
              {
                Flag=true;
                break;
              }
            if (!Flag) //a大学比b大学一定强。
            {
                Add(a,b); //建立一条有向边。
                In[b]++; //入度。
            }
        }
    for (int a=1;a<=n;a++)
      if (!In[a])
        Ans=max(Ans,DFS(a));
    printf("%d",Ans);
    return 0;
}
posted @ 2016-10-28 08:49  前前前世。  阅读(378)  评论(0编辑  收藏  举报