POJ No.3169 Layout

將已知條件抽象:

d[i+1] + 0  >=  d[i]

d[AL]+DL  >=  d[BL]

d[BD]+(-DD)  >=  d[AD]

 

問題爲:

滿足以上諸多條件的情況下,求出d[n] – d[1]的最大值。

即求d[1]+ MAX>=d[n] 中MAX的值。

 

 分析:

1)d[i]+x >= d[j]  d[k]+y>= d[i] 則有d[k]+(x+y)>=d[i]

符合遞推特性

 

2)d[m]+x>=d[n]

如若d[n]可由多個d[m]{m屬於1到N}轉移得到,又由於各個方程需要同時滿足,故取各個d[n]中的最小值

 

以上分析可得

d[n] = min{d[m] + x爲兩者差}

 

具體思路:

將方程以圖論模型中的邊表示

struct link

{

       int from;

       int to;

       int cost;

};    //  from + cost >=  to

 

 轉化爲最短路問題求解

 

算法主體思想:

 

不斷由邊更新每個點的值,如有解則可在 點數*邊數時間,即O(N*(N+ML+MD))內完成所有點值的更新。



#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define INF 1e9

using namespace std;

struct LL
{
	int from;
	int to;
	int cost;
}; // d[from] + cost >= d[to]

LL link[20010];
int d[1010];

int main()
{
	int num_node, num_link1, num_link2;
	scanf("%d %d %d", &num_node, &num_link1, &num_link2);
	fill(d, d + num_node, INF);
	d[0] = 0;

	// preparing for graph
	for (int i = 0; i < num_link1; ++i)
	{
		int AL, BL, DL; // d[AL] + DL >= d[BL]
		scanf("%d %d %d", &AL, &BL, &DL);
		link[i].from = AL-1;
		link[i].to = BL-1;
		link[i].cost = DL;
	}
	for (int i = num_link1; i < num_link1 + num_link2; ++i)
	{
		int AD, BD, DD; // d[BD] + (-DD) >= d[AD]
		scanf("%d %d %d", &AD, &BD, &DD);
		link[i].from = BD-1;
		link[i].to = AD-1;
		link[i].cost = -DD;
	}

	for (int i = 0; i < num_node; ++i)
	{
		for (int j = 0; j+1 < num_node; ++j)
			if(d[j+1]<INF)
				d[j] = min(d[j], d[j+1]);

		for (int j = 0; j < num_link1+num_link2; ++j)
			if(d[link[j].from]<INF)
				d[link[j].to] = min(d[link[j].to], d[link[j].from]+link[j].cost);
	}

	int res = d[num_node-1];
	if(d[0] < 0)
		res = -1;
	else if(res == INF)
		res = -2;

	printf("%d\n", res);
}


發佈了30 篇原創文章 · 獲贊 0 · 訪問量 9154
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章