zoukankan      html  css  js  c++  java
  • topsort模板,poj 2585

    今天总结topsort模板,学习了书上的那种方法

    另外也做了一题。。

    http://poj.org/problem?id=2585

    貌似网上也都是这种做法 ?

    先贴第一个代码

    #include<cstdio>
    #include<cstring>
    const int maxn = 50000 + 10;
    struct edge{
        int to, w;
        edge * next;
    }*list[maxn];
    void add_edge(int u, int v,int w){
        edge *tmp = new edge;
        tmp->to = v;
        tmp->w = w;
        tmp->next = list[u];
        list[u] = tmp;
    }
    int n, m;
    int ind[maxn];//入度
    char output[100];
    void topsort(){
        int top = -1;
        edge *tmp;
        bool bcycle = false;//判断是否存在有向环
        int pos = 0;//写入output数组的位置
        for(int i = 0; i < n; i ++){//入度为0的顶点入栈
            if(ind[i] == 0){
                ind[i] = top;
                top = i;
            }
        }
        for(int i = 0; i < n; i ++){
            if(top == -1){
                bcycle = true;
                break;
            }else{
                int j = top;
                top = ind[top];
                pos += sprintf(output + pos , "%d ", j + 1);
                tmp = list[j];
                while(tmp != NULL){
                    int k = tmp->to;
                    if((-- ind[k]) == 0){
                        ind[k] = top;
                        top = k;
                    }
                    tmp = tmp->next;
                }
            }
        }
        if(bcycle)
          puts("network has a cycle!");
        else{
            output[strlen(output) - 1] = 0;
            printf("%s\n", output);
        }
    }
    int main(){
        while(~scanf("%d%d", &n ,&m)){
            memset(list, 0, sizeof(list));
            memset(ind, 0, sizeof(ind));
            memset(output, 0, sizeof(output));
            for(int i = 0; i < m; i ++){
                int u, v;
                scanf("%d%d", &u, &v);
                u--; v--;
                ind[v] ++;
                add_edge(u, v, 0);
            }
            topsort();
            for(int i = 0; i < n; i ++){
                edge *tmp = list[i];
                while(tmp != NULL){
                    list[i] = tmp->next;
                    delete tmp;
                    tmp = list[i];
                }
            }
        }
        return 0;
    }
    /*
    6 8 
    1 2
    1 4
    2 6
    3 2
    3 6
    5 1
    5 2
    5 6
    6 8
    1 3
    1 2
    2 5
    3 4
    4 2
    4 6
    5 4
    5 6
    
    5 1 4 3 2 6
    network has a cycle!
    */

    第二个就是这题的代码了

    #include<cstdio>
    #include<cstring>
    #include<string>
    using namespace std;
    
    string cover[4][4];
    void init(){
        /*
        for(int i = 0; i < 4; i ++){
            for(int j = 0; j < 4; j ++)
              cover[i][j].erase();
        }
        */
        for(int k = 1; k <= 9; k ++){
            int i = (k-1) / 3;
            int j = (k-1) % 3;
            cover[i][j] += char(k + '0');
            cover[i+1][j] += char(k + '0');
            cover[i][j+1] += char(k + '0');
            cover[i+1][j+1] += char(k + '0');
        }
    }
    int ind[10];
    bool g[10][10];
    int screen[5][5];
    bool exist[10];
    int t = 0;
    void calc(){
        memset(ind, 0, sizeof (ind));
        memset(g, 0, sizeof (g));
        memset(exist, 0, sizeof (exist));
        t = 0;
        for(int i = 0; i < 4; i ++){
            for(int j = 0; j < 4; j ++){
                int k;
                scanf("%d", &k);
                screen[i][j] = k;
                if(!exist[k]) t ++;
                exist[k] = true;
            }
        }
    }
    void build(){
        for(int i = 0; i < 4; i ++){
            for(int j = 0; j < 4; j ++){
                for(int k = 0; k < cover[i][j].length(); k ++){
                    /*
                    if( (g[screen[i][j]][cover[i][j][k]-'0'] == 0) &&
                                screen[i][j] != cover[i][j][k] - '0'){
                        g[screen[i][j]][cover[i][j][k]-'0'] = true;
                        ind[cover[i][j][k] - '0'] ++;
                    }
                    */
                    int u = screen[i][j];
                    int v = cover[i][j][k]-48;
                    if(g[u][v] == 0 && u != v){
                        g[u][v] = true;
                        ind[v] ++;
                    }
                }
            }
        }
    }
    bool check(){
    /*
        for(int j = 0; j < t; j ++){
            int i = 1;
            while( !exist[i] || ( i <= 9 && ind[i] >0))
              i ++;//这个很好
            if(i > 9)return false;//说明入度都大于0了,那么就存在环了 
            exist[i] = false;
            int k = i;
            for(i = 1; i <= 9; i++){
                if(exist[i] && g[k][i])
                  ind[i] --;
            }
        }
        return true;
    */
       // for(int i = 1; i <= 9; i ++)printf("++  %d %d\n", i, ind[i]);
        for(int i = 1; i <= 9; i ++){
            for(int j = 1; j <= 9; j ++){
                if(ind[j] == 0){
                    ind[j] = -1;
                    for(int k = 1; k <= 9; k ++){
                        if(g[j][k] == false) continue;
                        ind[k] --;
                    }
                }
            }
        }
        //for(int i = 1; i <= 9; i ++)printf("--  %d %d\n", i, ind[i]);
        int flag = 0;
        for(int i = 1; i <= 9; i ++){
            if(ind[i] != -1){
                flag = 1;
                break;
            }
        }
        if(flag)
          return false;
        else
          return true;
    
    }
    int main(){
        init();
        char s[15];
        while(~scanf("%s", s)){
            if(strcmp(s, "ENDOFINPUT") == 0) break;
            calc();
            build();
            if(check())
              puts("THESE WINDOWS ARE CLEAN");
            else
              puts("THESE WINDOWS ARE BROKEN");
            scanf("%s", s);
        }
        return 0;
    }

    就记到这里吧。。。

    妹子,晚安

    -------------------------更新--------------------------

    昨天多校有一题,数据弱。。我直接用的topsort也能过

    写的时候,自己总结了一咱判环的方法,当然原理还是那样的

    http://acm.hdu.edu.cn/showproblem.php?pid=4324

    #include<cstdio>
    #include<cstring>
    
    char map[2010][2010];
    int ind[2010];
    int vis[2010];
    int main(){
        int tcase;
        scanf("%d", &tcase);
        int z = 1;
        while(tcase --){
            int n;
            scanf("%d", &n);
            memset(vis, -1, sizeof vis);
            for(int i = 0; i < n;i  ++){
                   scanf("%s", map[i]);
                for(int j = 0; map[i][j]; j ++)
                  if(map[i][j] == '1')
                    ind[j] ++;
            }
            int flag = 0;
            for(int i = 0; i < n; i ++){
                int j = 0;
                while(j < n && ind[j] != 0)
                  j ++;
                if(j >= n){
                    flag = 1;
                    break;
                }
                ind[j] --;
                for(int k = 0; map[j][k]; k ++){
                    if(map[j][k] == '1'){
                        ind[k] --;
                    }
                }
            }
            printf("Case #%d: ", z++);
            if(flag)
              puts("Yes");
            else
              puts("No");
        }
        return 0;
    }
  • 相关阅读:
    POJ 2752 Seek the Name, Seek the Fame
    POJ 2406 Power Strings
    KMP 算法总结
    SGU 275 To xor or not to xor
    hihocoder 1196 高斯消元.二
    hihoCoder 1195 高斯消元.一
    UvaLive 5026 Building Roads
    HDU 2196 computer
    Notions of Flow Networks and Flows
    C/C++代码中的笔误
  • 原文地址:https://www.cnblogs.com/louzhang/p/2616176.html
Copyright © 2011-2022 走看看