当前位置: 首页 > 工具软件 > Tarzan > 使用案例 >

CodeForces - 1131D-(Gourmet choice )(并查集+tarzan缩点+拓扑排序)(简单偏中等题)

慕仲渊
2023-12-01

题意:第一天有n道菜,第二天有m道菜,给出第一天每道菜跟第二天每道菜比较的结果,存在“=”,“<”,“>”三种结果,根据该结果对所有菜进行一个等级的划分,并要求菜的最大等级要尽量小。
题解:乍一看蛮像拓扑排序的,其实就是拓扑排序,只不过存在“=”这种比较结果,不过也很好处理,根据并查集将=的划分在同一个生成树里面,即利用tarzan缩点,最后跑一遍拓扑排序就好了。
hint:不知道为啥这个拓扑排序我用queue就WA用stack就AC,很奇怪。
附上ACcode:

#include <bits/stdc++.h>
#define FOPI freopen("INPUT.TXT", "r", stdin)
#define DOPI freopen("OUTPUT.TXT", "w", stdout)
#define FOR(i, x, y) for(int i = x; i <= y; i ++)
#define ROF(i, x, y) for(int i = x; i >= y; i --)
using namespace std;
typedef long long int ll;
const int ind=0x3f3f3f3f,N=1e3+10;
int f[N*N];
char ch[N][N];
int n,m;
int getf(int x){return f[x]==x?x:f[x]=getf(f[x]);}
vector<int> v[N*N];
int cnt[N*N];
int book[N*N];
int ans[N*N];
void dfs()
{
    stack<int> q;
    for(int i=1;i<=n+m;i++)book[i]=0;
    for(int i=1;i<=n+m;i++){
        int fi=getf(i);
        if(!cnt[fi]){
            q.push(fi);
            book[fi]=1;
            ans[fi]=1;
        }
    }
    while(!q.empty()){
        int ti=q.top();
        q.pop();
        for(int i=0;i<v[ti].size();i++){
            if(--cnt[v[ti][i]]==0&&book[v[ti][i]]==0){
             ans[v[ti][i]]=ans[ti]+1;  book[v[ti][i]]=1; q.push(v[ti][i]);}
        }
//        cout << "here" << endl;
    }

}
void merge_it(int x,int y)
{
    int xx=getf(x);
    int yy=getf(y);
    if(xx!=yy)f[xx]=yy;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n+m;i++)f[i]=i;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>ch[i][j];
            if(ch[i][j]=='='){
                merge_it(i,n+j);
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(ch[i][j]=='<'){
               int fi=getf(i);
               int fj=getf(j+n);
               v[fi].push_back(fj);
               cnt[fj]++;
            }
            else if(ch[i][j]=='>'){
                int fi=getf(i);
                int fj=getf(j+n);
                v[fj].push_back(fi);
                cnt[fi]++;
            }
        }
    }
      dfs();
      for(int i=1;i<=n+m;i++){
        if(book[getf(i)]==0){
            cout << "No" << endl;return 0;
        }
      }
      cout << "Yes" << endl;
      for(int i=1;i<=n;i++){
        if(i==1)cout << ans[getf(i)];
        else cout << ' ' << ans[getf(i)];
      }cout << endl;
      for(int i=n+1;i<=n+m;i++){
        if(i==n+1)cout << ans[getf(i)];
        else cout << ' ' << ans[getf(i)];
      }cout << endl;
    return 0;
}
 类似资料: