最长路问题

定义:最长路一般用在DAG上,也即为从DAG上的某点到大另外一点走的最长路径

应用举例:嵌套矩形

有n个矩形,每个矩形用两个整数a,b描述,分别表示长和宽,矩形X(a,b)可以嵌套到矩形X(c,d)内当且仅当a<c, b<d,也可以通过选择矩形得到嵌套关系,即a<d,b<c,现在的问题是求出尽量多的矩形,使得前面的矩形可以嵌套在所有后面的矩形内。

推广:二维情况可以推广到n维

解答:首先讲矩形嵌套关系定义为有向图的边,这样就可以建立一个有向图DAG,然后求DAG上的最长路即可

最长路的求法:若i->j有边,则d[j] = d[i] +1,枚举所有可以到达j的点,求最大值即可

下面给出嵌套问题的n为情况的代码

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

#define K 30
#define N 10

int boxes[K][N];
int G[K][K];
int d[K];

bool Nest(int s, int e, int n)
{
	int i;
	for (i = 0; i < n; i++)
		if (boxes[s][i] >= boxes[e][i])
			break;
	if (i < n)
		return false;
	else
		return true;
}

int dp(int s, int k)
{
	if (d[s] > 0)
		return d[s];
	d[s] = 1;
	for (int i = 0; i < k; i++)
	{
		if (G[i][s])
			d[s] = d[s] > dp(i, k) + 1 ? d[s] : d[i] + 1;
	}
	return d[s];
}

void PrintPath(int s, int e, int k)
{
	int i;
	for (i = 0; i < k; i++)
		if (G[i][s] && d[i] + 1 == d[s])
			break;
	if (i < k)
		PrintPath(i, e, k);
	printf("%d", s + 1);
	if (s == e)
		printf("\n");
	else
		printf(" ");
}

int main(void)
{
	int k, n;
	while (scanf("%d%d", &k, &n) != EOF)
	{
		int i, j;
		for (i = 0; i < k; i++)
		{
			for (j = 0; j < n; j++)
				scanf("%d", &boxes[i][j]);
			sort(boxes[i], boxes[i] + n);
		}
		memset(G, 0, sizeof(G));
		memset(d, -1, sizeof(d));
		for (i = 0; i < k; i++)
		{
			for (j = 0; j < k; j++)
			{
				if (Nest(i, j, n))
					G[i][j] = 1;
			}
		}
		int index = 0;
		for (i = 0; i < k; i++)
		{
			int len = dp(i, k);
			if (d[i] > d[index])
			{
				index = i;
			}
		}
		printf("%d\n", d[index]);
		PrintPath(index, index, k);

	}

	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章