Codeforces #541 (Div2) - D. Gourmet choice(拓扑排序+并查集)

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 }

 

posted on 2019-04-27 18:50  随缘&不屈  阅读(138)  评论(0编辑  收藏  举报

导航