Problem Codeforces #541 (Div2) - D. Gourmet choice
Time Limit: 2000 mSec
Problem Description
Input
Output
The first line of output should contain "Yes", if it's possible to do a correct evaluation for all the dishes, or "No" otherwise.
If case an answer exist, on the second line print nn integers — evaluations of dishes from the first set, and on the third line print mm integers — evaluations of dishes from the second set.
Sample Input
3 4
>>>>
>>>>
>>>>
Sample Output
Yes
2 2 2
1 1 1 1
题解:一看就是拓扑排序,一通敲之后发现第三个样例过不去,原因是没有妥善处理等号的问题,其实很容易解决,相等的节点缩成一个,用并查集很容易实现,之后再拓扑排序就没问题了。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i, n) for (int i = 1; i <= (n); i++) 6 #define sqr(x) ((x) * (x)) 7 8 const int maxn = 2000 + 10; 9 const int maxm = 200000 + 100; 10 const int maxs = 10000 + 10; 11 12 typedef long long LL; 13 typedef pair<int, int> pii; 14 typedef pair<double, double> pdd; 15 16 const LL unit = 1LL; 17 const int INF = 0x3f3f3f3f; 18 const LL mod = 1000000007; 19 const double eps = 1e-14; 20 const double inf = 1e15; 21 const double pi = acos(-1.0); 22 23 int n, m; 24 string str[maxn]; 25 vector<int> G[maxn]; 26 int deg[maxn], ans[maxn]; 27 int fa[maxn]; 28 int Min, tot; 29 30 int findn(int x) 31 { 32 return x == fa[x] ? x : fa[x] = findn(fa[x]); 33 } 34 35 void merge(int x, int y) 36 { 37 int fx = findn(x), fy = findn(y); 38 if (fx != fy) 39 { 40 fa[fx] = fy; 41 } 42 } 43 44 bool toposort() 45 { 46 queue<int> que; 47 Min = 0; 48 int cnt = 0; 49 for (int i = 0; i < n + m; i++) 50 { 51 if (findn(i) == i && !deg[i]) 52 { 53 que.push(i); 54 cnt++; 55 ans[i] = 0; 56 } 57 } 58 while (!que.empty()) 59 { 60 int u = que.front(); 61 que.pop(); 62 for (auto v : G[u]) 63 { 64 int fv = findn(v); 65 if (fv == v) 66 { 67 deg[fv]--; 68 if (!deg[fv]) 69 { 70 cnt++; 71 que.push(fv); 72 ans[fv] = ans[u] - 1; 73 Min = min(ans[fv], Min); 74 } 75 } 76 } 77 } 78 return cnt == tot; 79 } 80 81 void output() 82 { 83 cout << "YES" << endl; 84 for (int i = 0; i < n; i++) 85 { 86 cout << ans[findn(i)] - Min + 1; 87 if (i != n - 1) 88 { 89 cout << " "; 90 } 91 else 92 { 93 cout << endl; 94 } 95 } 96 for (int i = n; i < n + m; i++) 97 { 98 cout << ans[findn(i)] - Min + 1; 99 if (i != n - 1) 100 { 101 cout << " "; 102 } 103 else 104 { 105 cout << endl; 106 } 107 } 108 } 109 110 void premanagement() 111 { 112 for (int i = 0; i < n + m; i++) 113 { 114 if (findn(i) == i) 115 { 116 tot++; 117 } 118 } 119 } 120 121 int main() 122 { 123 ios::sync_with_stdio(false); 124 cin.tie(0); 125 //freopen("input.txt", "r", stdin); 126 //freopen("output.txt", "w", stdout); 127 cin >> n >> m; 128 for(int i = 0; i < n + m; i++) 129 { 130 fa[i] = i; 131 } 132 for (int i = 0; i < n; i++) 133 { 134 cin >> str[i]; 135 } 136 for (int i = 0; i < n; i++) 137 { 138 for (int j = 0; j < m; j++) 139 { 140 if (str[i][j] == '=') 141 { 142 merge(i, n + j); 143 } 144 } 145 } 146 for (int i = 0; i < n; i++) 147 { 148 for (int j = 0; j < m; j++) 149 { 150 if (str[i][j] == '>') 151 { 152 int fi = findn(i), fj = findn(n + j); 153 G[fi].push_back(fj); 154 deg[fj]++; 155 } 156 else if (str[i][j] == '<') 157 { 158 int fi = findn(i), fj = findn(n + j); 159 G[fj].push_back(fi); 160 deg[fi]++; 161 } 162 } 163 } 164 premanagement(); 165 bool ok = toposort(); 166 if (!ok) 167 { 168 cout << "NO" << endl; 169 } 170 else 171 { 172 output(); 173 } 174 return 0; 175 }