题目大意:有n个三维三维向量,c[i]=(x,y,z),定义c[i]<c[j]当且仅当c[i].x<c[j].x&&c[i].y<c[j].y&&c[i].z<c[j].z,现要求给每一个c[i]赋值一个数w[i],使w[i]的大小能够反映c[i]之间的大小关系,求满足w[1]=w[2],问有无合法的w[i],有则输出一种方案
2<=n<=1000;0<=x[i],y[i],z[i]<=255
思路:考虑从满足c[i]<c[j]的i和j 之间建立映射关系,可以发现,如果有多个i,满足c[i]<c[j],那么w[j],应该等于所有满足关系的w[i]的最大值再+1,也就是如果从最小的点开始bfs,当子节点的所有父结点的w都求出来后再更新子节点的w。
那么就变成了类似于求拓扑序的过程,求出每个点的入度,初始将所有最小的也就是入度为0的点放入队列,每访问一个点就令其入度-1,同时更新ans[v]=max(ans[v],ans[u]+1),入度为0后放入队列
考虑w[1]和w[2]应该相等的问题,如果c[1]c[2]之间是有明确的大小关系的,那么显然不合法,如果合法的话,我我们就将他们的w[i]统一成最大的那一个,这样原先比他们小的依然是符合条件的,但比他们大的有可能不符合条件,所以需要再跑一遍拓扑排序,得到的新的答案一定是符合所有映射关系的
#include<bits/stdc++.h>
//#include<__msvc_all_public_headers.hpp>
using namespace std;
typedef long long ll;
const int N = 1e3 + 10;
int n;
int ans[N];
int in[N];
vector<int>g[N];
int in2[N];
void init()
{
for (int i = 1; i <= n; i++)
{
in[i] = 0;
g[i].clear();
ans[i] = 0;
in2[2] = 0;
}
}
struct node
{
int r, g, b;
node(int a, int d, int c)
{
r = a, g = d, b = c;
}
node()
{
}
}a[N];
void solve()
{
cin >> n;
init();
for (int i = 1; i <= n; i++)
{
int r, g, b;
cin >> r >> g >> b;
a[i] = { r, g, b };
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (a[i].r < a[j].r && a[i].g < a[j].g && a[i].b < a[j].b)
{//有明确大小关系的建立映射关系
in[j]++;
in2[j]++;//因为要求两遍拓扑,所以建一个备用
g[i].push_back(j);
}
}
}
queue<int>q;
for (int i = 1; i <= n; i++)
{
if (!in[i])
{//入度为0的点入队
q.push(i);
}
}
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
in[v]--;
ans[v] = max(ans[v],ans[u]+1);//子节点是父结点w的最大值
if(!in[v])
q.push(v);//入度为0入队
}
}
if (!(a[1].r < a[2].r && a[1].g < a[2].g && a[1].b < a[2].b) && !(a[1].r > a[2].r && a[1].g > a[2].g && a[1].b > a[2].b))
{//c[1]c[2]是合法的
for (int i = 1; i <= n; i++)
{
in[i] = in2[i];
}
ans[1] = max(ans[1], ans[2]);
ans[2] = max(ans[1], ans[2]);//两者w[i]取最大值再跑一遍拓扑
for (int i = 1; i <= n; i++)
{
if (!in[i])
{
q.push(i);
}
}
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
ans[v] = max(ans[v], ans[u] + 1);
in[v]--;
if (!in[v])
q.push(v);
}
}
}
else
{
cout << -1 << endl;
return;
}
for (int i = 1; i <= n; i++)
{
cout << ans[i] << endl;
}
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
t=1;
while (t--)
{
solve();
}
return 0;
}
//7
//3 3 3
//3 1 1
//0 0 0
//1 1 2
//1 1 2
//4 2 2
//5 4 4
//6
//3 3 3
//3 0 1
//0 0 0
//1 1 2
//1 1 2
//4 1 2
//6
//3 3 3
//3 1 1
//0 0 0
//1 1 2
//1 1 2
//4 1 2
//5
//3 3 3
//3 0 1
//0 0 0
//1 1 2
//1 1 2
//
//6
//0 0 0
//0 1 2
//1 1 1
//2 2 2
//2 3 2
//3 3 3
//
//3
//0 0 0
//2 2 2
//1 1 1
//
//3
//1 0 0
//0 1 0
//0 0 1
//
//3
//0 0 0
//0 1 2
//255 255 255