NYOJ208 Supermarket(续)

前面用贪心算法解决的方案也可以AC,但是对于每一个数据,都要从它的deadline开始寻找,最坏的情况是O(n^2)。所以这里用并查集来优化查找的步骤。
怎么优化,其实这个思想在NYOJ207食物链那道题里面就有体现。并查集有两个功能,查找根节点和合并根节点,如果每一条路径都比较短的话,查找的效率就会很高。怎么样使每条路径都比较短呢?那就是尽可能的将所有节点直接连接到根节点,也就是呈现一个星形。比如要加入一个节点,就必须逐步的更新根节点到该节点父节点以前的所有节点的父节点,使它们都直接与根节点相连。这种条件下,内存要多一点(N*3字节),但时间会快很多(至少200ms)。

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

const int N = 10005;

int arr[N][2];

int parent[N];

int compare(const void *a, const void *b)

{

	int *p1 = (int *)a;

	int *p2 = (int *)b;

	return p2[0] - p1[0];

}

int Find(int x)

{

	if(parent[x] == -1)

		return x;

	parent[x] = Find(parent[x]);

	return parent[x];

}

int main()

{

	int n,i;

	int r,sum;

	while(scanf("%d", &n) != EOF)

	{

		memset(parent, -1, sizeof(parent));

		for(i = 0; i < n; ++i)

			scanf("%d %d", &arr[i][0], &arr[i][1]);

		qsort(arr, n, 2*sizeof(int), compare);

		sum = 0;

		for(i = 0; i < n; ++i)

		{

			r = Find(arr[i][1]);

			if(r > 0)//如果有日期可用

			{

				sum += arr[i][0];

				parent[r] = Find(r - 1);

			}

		}

		printf("%d\n", sum);

	}

}


 

 


 

你可能感兴趣的:(super)