D. Gourmet choice
题目链接:https://codeforces.com/problemset/problem/1131/D
题目大意:NULL
解题思路:如过两个菜之间是等号的话,则他们的序号应该相同,因此我们需要进行缩点操作,
这里需要用到并查集,然后就是判断菜之间的顺序,因为他们之间有一个关系,我们可以考虑在两点之间建边,这时候就需要用到
拓扑排序即可
#includeusing namespace std; typedef long long ll; const int maxn=1e4+10; int pre[maxn],in[maxn],out[maxn],vis[maxn],ans[maxn]; vector<int>g[maxn]; int find(int i) { if(i==pre[i]) return pre[i]; else return find(pre[i]); } void unions(int x,int y) { int xx=find(x); int yy=find(y); if(xx!=yy) pre[xx]=yy; } int main() { int n,m; cin>>n>>m; for(int i=1;i<=n+m;i++) { pre[i]=i; } char s[1100][1100]; for(int i=1;i<=n;i++) { scanf("%s",s[i]+1); for(int j=1;j<=m;j++) { if(s[i][j]=='=') unions(i,j+n); /*else if(s[i][j]=='>') g[find(j+n)].push_back(find(i)),in[find(i)]++; else g[find(i)].push_back(find(j+n)),in[find(j+n)]++;*/ } } for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++) if(s[i][j] == '>'){ g[find(j+n)].push_back(find(i)); in[find(i)]++; } else if(s[i][j] == '<') g[find(i)].push_back(find(j+n)),in[find(j+n)]++; } stack<int>q; for(int i=1;i<=n+m;i++) { if(in[find(i)]==0) { // cout< q.push(find(i)); vis[find(i)]=1; ans[find(i)]=1; } } while(!q.empty()) { int u=q.top(); q.pop(); for(int i=0;i int v=g[u][i]; in[find(v)]--; if(in[find(v)]==0&&!vis[find(v)]) { vis[find(v)]=1; ans[find(v)]=ans[find(u)]+1; q.push(find(v)); } } } for(int i=1;i<=n+m;i++) { if(!vis[find(i)]) { cout<<"NO\n"; return 0; } } cout<<"YES"<<endl; for(int i=1;i<=n;i++) { if(i!=1) cout<<" "; cout<<ans[find(i)]; } cout<<endl; for(int i=1;i<=m;i++) { if(i!=1) cout<<" "; cout<) { n)]; } return 0; }