CF #541div2 D
题目本质:形成一个拓扑图,不应带自环。
解决方法:
1.先把等于号的部分用dsu缩点;
2.大于和小于号建立拓扑关系;
3.n*m的矩阵,只要用标号n+j代表m集合的第j个就从二维降到一维了;
4.dfs查有没有环:used == 2的那种环是合法的!
1 void dfs(int i) { 2 used[i] = 1; 3 for (int s : v[i]) { 4 if (used[s] == 1) { 5 puts("No"); 6 exit(0); 7 } 8 if (!used[s]) dfs(s); 9 } 10 used[i] = 2; 11 order.push_back(i); 12 }
5.按照order记录的拓扑顺序自底向上dp一下最小取值。
总代码:
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <ctime> 7 #include <cctype> 8 #include <climits> 9 #include <iostream> 10 #include <iomanip> 11 #include <algorithm> 12 #include <string> 13 #include <sstream> 14 #include <stack> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <vector> 19 #include <list> 20 #include <fstream> 21 #define ri readint() 22 #define gc getchar() 23 #define R(x) scanf("%d", &x) 24 #define W(x) printf("%d\n", x) 25 #define init(a, b) memset(a, b, sizeof(a)) 26 #define rep(i, a, b) for (int i = a; i <= b; i++) 27 #define irep(i, a, b) for (int i = a; i >= b; i--) 28 #define ls p << 1 29 #define rs p << 1 | 1 30 using namespace std; 31 32 typedef double db; 33 typedef long long ll; 34 typedef unsigned long long ull; 35 typedef pair<int, int> P; 36 const int inf = 0x3f3f3f3f; 37 const ll INF = 1e18; 38 39 inline int readint() { 40 int x = 0, s = 1, c = gc; 41 while (c <= 32) c = gc; 42 if (c == '-') s = -1, c = gc; 43 for (; isdigit(c); c = gc) 44 x = x * 10 + c - 48; 45 return x * s; 46 } 47 48 const int maxn = 1e3 + 5; 49 int n, m; 50 int value[maxn << 1]; 51 int used[maxn << 1]; 52 int fa[maxn << 1]; 53 char cmp[maxn][maxn]; 54 vector<int> v[maxn << 1], order; 55 56 int getf(int v) { 57 return v == fa[v] ? v : fa[v] = getf(fa[v]); 58 } 59 60 void merge(int x, int y) { 61 int p = getf(x), t = getf(y); 62 fa[p] = t; 63 } 64 65 void dfs(int i) { 66 used[i] = 1; 67 for (int s : v[i]) { 68 if (used[s] == 1) { 69 puts("No"); 70 exit(0); 71 } 72 if (!used[s]) dfs(s); 73 } 74 used[i] = 2; 75 order.push_back(i); 76 } 77 78 int main() { 79 ios_base::sync_with_stdio(false); 80 cin.tie(0); 81 82 cin >> n >> m; 83 rep(i, 1, n + m) { 84 fa[i] = i; 85 } 86 87 rep(i, 1, n) { 88 rep(j, 1, m) { 89 cin >> cmp[i][j]; 90 if (cmp[i][j] == '=') { 91 merge(i, n + j); 92 } 93 } 94 } 95 96 rep(i, 1, n) { 97 rep(j, 1, m) { 98 int x = getf(i), y = getf(n + j); 99 if (cmp[i][j] == '>') { 100 v[x].push_back(y); 101 } else if (cmp[i][j] == '<') { 102 v[y].push_back(x); 103 } 104 } 105 } 106 107 rep(i, 1, n + m) { 108 if (fa[i] != i) 109 continue; 110 if (!used[i]) { 111 dfs(i); 112 } 113 } 114 for (int i : order) { 115 int val = 0; 116 for (int j : v[i]) { 117 val = max(val, value[j]); 118 } 119 value[i] = val + 1; 120 } 121 122 cout << "Yes\n"; 123 rep(i, 1, n) { 124 cout << value[getf(i)] << " "; 125 } 126 cout << endl; 127 rep(i, 1, m) { 128 cout << value[getf(n + i)] << " "; 129 } 130 return 0; 131 }