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;
    }
  • 相关阅读:
    调用外部程序主窗体做子窗体
    查看window编码
    c# 数据库更新和界面刷新的问题
    c# datagridview代码(网上的)
    winform DataGridView控件的打印
    西电ubuntu更新软件源
    C++ primer 学习笔记(2):函数
    C++ Primer 学习笔记(1)——迭代器,数组
    查询表属于哪个数据
    oracle 实用语句
  • 原文地址:https://www.cnblogs.com/louzhang/p/2616176.html
Copyright © 2011-2022 走看看