• Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序


    https://codeforces.com/contest/1131/problem/D

    题意

    给你一个n*m二维偏序表,代表x[i]和y[j]的大小关系,根据表构造大小分别为n,m的x[],y[],使得两个数组中最大的数尽量小

    题解

    • 按照偏序表,构造出从小到大的拓扑图
    • 如何解决相等的数的偏序关系?
      • 用并查集缩点后再进行拓扑排序
    • 如何解决最大的数最小?
      • 只需要使得同一层的数相同就行,可以一批处理栈中的元素,对于一批栈中的元素产生的新点,先放进一个容器里,然后等到这批栈清空了,再把这个容器中的点放进栈中

    坑点

    • 需要标记已经进栈的并查集,防止同一个并查集重复进栈

    代码

    #include<bits/stdc++.h>
    #define M 4005
    using namespace std;
    int n,m,i,j,in[M],u,v,c[M],cnt;
    char s[M][M];
    stack<int>S;
    queue<int>Q;
    vector<int>g[M];
    int fa[M];int fin(int u){return fa[u]==u?u:fa[u]=fin(fa[u]);}
    void merge(int u,int v){
    	int x=fin(u),y=fin(v);
    	if(x!=y)fa[x]=y;
    }
    int main(){
    	cin>>n>>m;
    	for(i=1;i<=n+m;i++)fa[i]=i;
    	for(i=1;i<=n;i++)scanf("%s",s[i]+1);
    	for(i=1;i<=n;i++){
    		for(j=1;j<=m;j++){
    			if(s[i][j]=='='){
    				merge(i,j+n);
    			}
    		}
    	}
        for(i=1;i<=n;i++){
    		for(j=1;j<=m;j++){
    			u=fin(i);v=fin(j+n);
    			if(s[i][j]=='>'){
    				in[u]++;g[v].push_back(u);
    			}else if(s[i][j]=='<'){
    				in[v]++;g[u].push_back(v);
    			}
    		}
    	}
    	cnt++;
    	for(i=1;i<=n+m;i++){
    		u=fin(i);
    		if(in[u]==0&&!c[u]){
    			S.push(u);
    			c[u]=cnt;
    		}
    	}
        while(!S.empty()||!Q.empty()){
    		if(!S.empty()){
    		  u=S.top();S.pop();
    		  for(i=0;i<g[u].size();i++){
    			v=g[u][i];in[v]--;
    			if(in[v]==0){
    				Q.push(v);
    			}
    		  }
    		}else{
    		   cnt++;
    		   while(!Q.empty()){	
    			   u=Q.front();Q.pop();
    			   c[u]=cnt;S.push(u);
    			   //cout<<u<<" "<<c[u]<<endl;
    		   }
    		}
    	}
    	for(i=1;i<=n+m;i++){
    		u=fin(i);
    		if(in[u]>0){cout<<"No";return 0;}
    	}
    	cout<<"Yes"<<endl;
    	for(i=1;i<=n+m;i++){
    		u=fin(i);
    		cout<<c[u]<<" ";
    		if(i==n)cout<<endl;
    	}
    }
    
  • 相关阅读:
    【android】string.xml中的一些错误
    【android】【转】class android.media.MediaPlayer
    【android】gallery 循环播放
    【android】使用handler更新UI
    【android】Textview部分字符高亮
    【android】AudioManager音量控制
    【Android】listview选中行字体变大
    整理模拟练习8 第三章 会计电算化的工作环境
    会计电算化模拟试题9
    第二章 会计电算化基本要求
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10509743.html
Copyright © 2020-2023  润新知