今天总结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; }