• [CF1131D] Gourmet choice


    有两个正整数序列 (a,b),长度分别为 (n,m)。给出所有 (a_i)(b_j) ((1le ile n,1le jle m)) 的大小关系(大于,小于或者等于),请构造出符合条件的 (a)(b)。如果无解,输出 NO。如果有多个解,输出 (a,b) 中最大元素最小的方案。

    Solution

    并查集将所有等于的数合并起来,然后建图拓扑排序,最后 check 一下拓扑排序的结果以检查是否有环

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 2005;
    
    int n,m,g[N][N],fa[N],a[N],b[N];
    char c[N][N];
    
    int find(int p) {
        return fa[p]==p ? p : fa[p]=find(fa[p]);
    }
    
    void merge(int p,int q) {
        p=find(p); q=find(q);
        if(p!=q) fa[p]=q;
    }
    
    void dfs(int p) {
        b[p]=1;
        for(int i=1;i<=n+m;i++) {
            if(g[p][i]) {
                if(b[i]) {
                    cout<<"No";
                    exit(0);
                }
                if(a[i]==0) dfs(i);
                a[p]=max(a[p],a[i]);
            }
        }
        b[p]=0;
        ++a[p];
    }
    
    signed main() {
        cin>>n>>m;
        for(int i=1;i<=n+m;i++) fa[i]=i;
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                cin>>c[i][j];
                if(c[i][j]=='=') {
                    merge(i,n+j);
                }
            }
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                if(c[i][j]=='<') {
                    g[find(j+n)][find(i)]=1;
                }
                if(c[i][j]=='>') {
                    g[find(i)][find(j+n)]=1;
                }
            }
        }
        for(int i=1;i<=n+m;i++) if(a[i]==0) dfs(i);
        cout<<"Yes"<<endl;
        for(int i=1;i<=n;i++) cout<<a[find(i)]<<" ";
        cout<<endl;
        for(int i=1;i<=m;i++) cout<<a[find(i+n)]<<" ";
        cout<<endl;
    }
    
    
  • 相关阅读:
    构建之法阅读笔记一
    android studio的安装以及配置
    github本地上传口令
    注册git hub
    易用性
    第六周学习总结
    大型分布式网站架构设计与实践阅读笔记(3)
    第五周学习总结
    大型分布式网站架构设计与实践阅读笔记(2)
    第四周学习总结
  • 原文地址:https://www.cnblogs.com/mollnn/p/12573077.html
Copyright © 2020-2023  润新知