LouZhang

导航

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;
}

 

posted on 2012-07-31 03:26  louzhang_swk  阅读(466)  评论(0编辑  收藏  举报