Simone and graph coloring ( 2020ICPC-昆明 ) (思维)

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明)
题解参考链接1
题解参考链接2

题意

给出一个长度为n的排列,排列中每个逆序对之间连接一条无向边。最终构成一个无向图。现在请你给这个无向图染色,使得每个相邻的节点颜色均不相同。问最少需要多少种颜色。( n ≤ 1 e 6 n \leq 1e6 n1e6)

输入

2
4
1 3 4 2
2
1 2

输出

2
1 1 1 2
1
1 1

思路①-树状数组

算法:从 n~1 枚举每一个数字 i ,在排列中找出数字i左边比 i 大的数,从这些数中选出颜色最大的一个颜色 c j c_j cj。则令数字 i 的颜色 c i = c j + 1 c_i = c_j + 1 ci=cj+1即可。
理解: 之所以倒序枚举数字i,是因为这样更新排列中数字的颜色后,方便通过树状数组直接找出i左边比i大的数中颜色的最大值

CODE-One

const int N = 1e6 + 6;
int a[N], b[N], c[N];
int n;
void add(int x, int y)
{
	while (x <= n)
		c[x] = max(c[x], y),
		x += x & -x;
}

int ask(int x)
{
	int maxn = 0;
	while (x)
		maxn = max(maxn, c[x]),
		x -= x & -x;
	return maxn;
}

int main()
{
	IOS;
	int T; cin >> T;
	while (T--)
	{
		cin >> n;
		for (int i = 0; i <= n; i++)
			b[i] = 0, c[i] = 0;
		for (int i = 1; i <= n; i++)
			cin >> a[i], b[a[i]] = i;
			//b数组记录数字i在排列a中的下标

		for (int i = n; i >= 1; i--)
		{
			int x = ask(b[i] - 1);
			a[b[i]] = x + 1;//此时a序列已经没用了,就用直接覆盖a数组来存结果
			//注意:需要按照排列的顺序记录每个数字的颜色
			add(b[i], x + 1);
		}
        
		cout << ask(n) << endl;
		for (int i = 1; i <= n; i++)
			cout << a[i] << " ";
		cout << endl;
	}

	return 0;
}

思路②-最长下降子序列

找出最长的下降子序列的长度即是最小的颜色数。。。原理不能完全理解。。。

CODE-Two

const int N = 1e6 + 6;
int a[N], b[N], c[N];
int n;

int main()
{
	IOS;
	int T; cin >> T;
	while (T--)
	{
		cin >> n;
		for (int i = 1; i <= n; i++)
			cin >> a[i];

		int len = 0;
		for (int i = n; i >= 1; i--)
		{
			if (a[i] > b[len])
			{
				b[++len] = a[i];
				c[i] = len;
			}
			else
			{
				int x = lower_bound(b + 1, b + len + 1, a[i]) - b;
				b[x] = a[i];
				c[i] = x;
			}
		}

		cout << len << endl;
		for (int i = 1; i <= n; i++)
			cout << c[i] << " ";
		cout << endl;
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

to cling

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值