USACO Frame Up 矩阵覆盖 拓扑排序
矩阵覆盖的题, 可以转化为拓扑排序。写这个拓扑排序废了好大的劲以后好好看看。代码如下:
/* ID: m1500293 LANG: C++ PROG: frameup */ #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int h, w; int x1[30], y1[30], x2[30], y2[30]; int ex[30]; //有没有出现 char Map[55][55]; int indeg[30]; int d[30][30]; int ans[30], nans; void dfs() //很精髓的拓扑排序 { bool flog = 0; for(int i=1; i<=26; i++) if(ex[i]) { flog = 1; break; } if(!flog) { for(int i=0; i<nans; i++) printf("%c", ans[i]+'@'); printf("\n"); return ; } for(int u=1; u<=26; u++) if(ex[u] && !indeg[u]) { ex[u] = 0; ans[nans++] = u; for(int v=1; v<=26; v++) if(d[u][v]) indeg[v]--; dfs(); ex[u] = 1; nans--; for(int v=1; v<=26; v++) if(d[u][v]) indeg[v]++; } } int main() { freopen("frameup.in", "r", stdin); freopen("frameup.out", "w", stdout); scanf("%d%d", &h, &w); for(int i=1; i<=h; i++) { scanf("%s", Map[i]+1); for(int j=1; j<=w; j++) { if(Map[i][j] == '.') continue; int id = Map[i][j] - '@'; if(!x1[id] || x1[id]>i) x1[id] = i; if(!y1[id] || y1[id]>j) y1[id] = j; if(!x2[id] || x2[id]<i) x2[id] = i; if(!y2[id] || y2[id]<j) y2[id] = j; ex[id] = 1; } } for(int u=1; u<=26; u++) if(ex[u]) { //横着扫 x1[u] x2[u] y1[u] -> y2[u] for(int y=y1[u]; y<=y2[u]; y++) { int id = Map[x1[u]][y] - '@'; if(id != u && !d[u][id]) d[u][id] = 1, indeg[id]++; id = Map[x2[u]][y] - '@'; if(id != u && !d[u][id]) d[u][id] = 1, indeg[id]++; } for(int x=x1[u]; x<=x2[u]; x++) { int id = Map[x][y1[u]] - '@'; if(id != u && !d[u][id]) d[u][id] = 1, indeg[id]++; id = Map[x][y2[u]] - '@'; if(id != u && !d[u][id]) d[u][id] = 1, indeg[id]++; } } nans = 0; dfs(); return 0; }