zoukankan      html  css  js  c++  java
  • Day4

    有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。 

    Input输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。 
    Output给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。 

    其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。 
    Sample Input

    4 3
    1 2
    2 3
    4 3

    Sample Output

    1 2 4 3

    思路:直接拓扑排序即可,输出要求字典序最小,那么DFS就不行,无法保证字典序,直接上优先队列,代码如下:
    插一手DFS代码(无字典序)
    const int maxm = 510;
    
    int G[maxm][maxm], vis[maxm], N, M;
    vector<int> ans;
    
    bool dfs(int x) {
        vis[x] = -1;
        for (int i = 1; i <= N; ++i) {
            if(G[x][i]) {
                if(vis[i] == -1)
                    return false;
                if(!vis[i] && !dfs(i))
                    return false;
            }
        }
        vis[x] = 1;
        ans.push_back(x);
        return true;
    }
    
    int main() {
        while(scanf("%d%d",&N,&M) != EOF) {
            memset(G, 0, sizeof(G)), ans.clear(), memset(vis, 0, sizeof(vis));
            for (int i = 0; i < M; ++i) {
                int t1,t2;
                scanf("%d%d", &t1, &t2);
                G[t1][t2] = 1;
            }
            for(int i = 1; i <= N; ++i)
                if(!vis[i])
                    if(!dfs(i))
                        break;
            int cnt = 0;
            for (auto i = ans.rbegin(); i != ans.rend(); ++i) {
                if(cnt++)
                    printf(" ");
                printf("%d", *i);
                if(cnt == N)
                    break;
            }
        }
        return 0;
    }
    View Code

        AC代码:

    const int maxm = 510;
    
    int N, M, in[maxm], G[maxm][maxm], ans[maxm], cnt;
    
    struct Node {
        int id;
        Node(int _id) : id(_id){}
    
        bool operator<(const Node &a) const {
            return a.id < id;
        }
    };
    
    int main() {
        while(scanf("%d%d", &N, &M) != EOF) {
            memset(in, 0, sizeof(in)), memset(G, 0, sizeof(G)), cnt = 0;
            for (int i = 0; i < M; ++i) {
                int t1, t2;
                scanf("%d%d", &t1, &t2);
                if(!G[t1][t2]) {
                    G[t1][t2] = 1;
                    in[t2]++;
                }
            }
            priority_queue<Node> q;
            for (int i = 1; i <= N; ++i) {
                if(!in[i])
                    q.push(Node(i));
            }
            while(!q.empty()) {
                Node p = q.top();
                q.pop();
                int u = p.id;
                ans[cnt++] = u;
                for (int i = 1; i <= N; ++i) {
                    if(G[u][i]) {
                        if(!--in[i])
                            q.push(Node(i));
                    }
                }
            }
            for(int i = 0; i < N; ++i) {
                if(i)printf(" ");
                printf("%d", ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    View Code

    注意读入判重,否则会影响入度的计算。

    
    
  • 相关阅读:
    EntityFramework4.5使用Expression类创建动态查询及动态查询导航属性
    EF 5.0 帮助类
    EF异常:“System.InvalidOperationException”类型的未经处理的异常在 mscorlib.dll 中发生
    EF框架学习手记
    Entity Framework 学习
    C#特性-表达式树
    LINQ to SQL 运行时动态构建查询条件
    一点css 基础
    JQuery 判断复选框是否选中
    Asp.Net Server.MapPath()用法
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11283018.html
Copyright © 2011-2022 走看看