并查集 拓扑1131D

没什么特别大的感慨

并查集的使用与拓扑的升级版本

链接:https://codeforces.com/problemset/problem/1131/D

代码:

//Problem:
//Date:
//Skill:
//Bug:
/////////////////////////////////////////Definations/////////////////////////////////////////////////
//循环控制
#define CLR(a) memset((a),0,sizeof(a))
#define F(i,a,b) for(int i=a;i<=int(b);++i)
#define F2(i,a,b) for(int i=a;i>=int(b);--i)
#define RE(i,n)  for(int i=0;i<int(n);i++)
#define RE2(i,n) for(int i=1;i<=int(n);i++)
//输入输出
//#define INC(c) do{scanf("%c",&c);}while(isspace(c))
//#define ON cout<<endl
#define PII pair<int,int>
using namespace std;
const int inf = 0x3f3f3f3f;
const long long llinf = 0x3f3f3f3f3f3f3f3f;
////////////////////////////////////////Options//////////////////////////////////////////////////////
typedef long long ll;
#define stdcpph
#define CPP_IO

#ifdef stdcpph
#include<bits/stdc++.h>
#else
#include<ctype.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<algorithm>
#include<functional>
#ifdef CPP_IO
#include<iostream>
#include<iomanip>
#include<string>
#else
#include<stdio.h>
#endif
#endif
////////////////////////////////////////Basic Functions//////////////////////////////////////////////
template<typename INint>
inline void IN(INint &x)
{
	x = 0; int f = 1; char c; cin.get(c);
	while (c<'0' || c>'9') { if (c == '-')f = -1; cin.get(c); }
	while (c >= '0'&&c <= '9') { x = x * 10 + c - '0'; cin.get(c); }
	x *= f;
}
template<typename INint>
inline void OUT(INint x)
{
	if (x > 9)OUT(x / 10);
	cout.put(x % 10 + '0');
}
////////////////////////////////////////Added Functions//////////////////////////////////////////////
const int maxn = int(1e3 + 5);
int n, m;
vector<int>fa(1,-1);
int ff(int x) {
	return fa[x] == x ? x : fa[x] = ff(fa[x]);
}
void mer(int x, int y)
{
	int fx = ff(x), fy = ff(y); fa[fx] = fy;
}
string ss[maxn];
int in[maxn * 2], res[maxn * 2];
int ma[maxn*2][maxn*2];
int ans[maxn * 2], rk[maxn * 2];
int topu(int n, int indegree[], int result[])//必须之前统计入度
{
	queue<int> Q; int cnt(0);
	for (int i = 1; i <= n; i++)if(fa[i]==i)
		if (indegree[i] == 0)
		{
			Q.push(i);//将 没有依赖顶点的节点入队
			rk[i] = 1;
			//result[cnt++] = i;
		}
	while (!Q.empty())  //
	{
		int u = Q.front();		Q.pop();//删除队顶元素 
		result[++cnt] = u;//将上边选出的没有依赖顶点的节点加入到排序结果中
		for (int i = 1; i <= n; i++)if (fa[i] == i)
		{
			if (ma[u][i])
			{
				rk[i] = max(rk[i], rk[u] + 1);
				indegree[i] --;//删去以u为顶点的边
				if (indegree[i] == 0) //如果节点i的所有依赖顶点连接边都已经删去
					Q.push(i);  //即变为无依赖顶点的节点   将其入队
			}
		}
	}
	return cnt;//返回成功确定顺序的节点数
}

////////////////////////////////////////////Code/////////////////////////////////////////////////////
int main()
{
	//freopen("C:\\Users\\VULCAN\\Desktop\\data.in", "r", stdin);
	int T(1), times(0);
#ifdef CPP_IO// CPP_IO
	std::ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	//cin >> T;
#else
	//IN(T);
#endif 
	/////////////////////////////////////////////////////////////////////////////////////////////////
	while (++times, T--)
	{
		cin >> n >> m;
		RE2(i, n + m)fa.push_back(i);
		RE2(i, n)cin >> ss[i];
		RE2(i, n)
		{
			RE2(j, m)
			{
				char c; c = ss[i][j - 1];
				if (c == '=') /*E[i].push_back(j + n), E[j + n].push_back(i),*/
					mer(i, j + n);
			}
		}
		RE2(i, n + m)fa[i] = ff(i);

		RE2(i, n)
		{
			RE2(j, m)
			{
				char c; c = ss[i][j - 1];
				//if (fa[i] == fa[j + n])continue;

				if (c == '<') ma[fa[i]][fa[j+n]] = 1;
				else if(c=='>') ma[fa[j+n]][fa[i]] = 1;
			}
		}
		RE2(i, n + m)RE2(j, n + m)if (ma[i][j])++in[j];
		bool flag = 1;
		RE2(i, n + m)if (ma[i][i])flag = 0;
		int amo(0);
		RE2(i, n + m)amo += fa[i] == i;
		int cnt=topu(n + m, in, res);

		if ((cnt != amo)|| !flag)
		{
			cout << "No" << endl; continue;
		}
		else cout << "Yes" << endl;
		//RE2(i, n + m)rk[res[i]] = i;
		RE2(i, n + m)
			ans[i] = rk[fa[i]];
		RE2(i, n)
		{
			if (i - 1)cout << ' ';
			cout << ans[i];
		}
		cout << endl;
		RE2(i, m)
		{
			if (i - 1)cout << ' ';
			cout << ans[i + n];
		}

		//cout << ans << endl;
	}
	///////////////////////////////////////////////////////////////////////////////////////////////////
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41046771/article/details/87987487