差分约束——HDOJ 3440

HDOJ 3440 House Man

/*
HDOJ 3440 house man
差分约束系统类型的题目,难点在建图
把每个房子作为一个顶点,然后按照高度排序
每两个顶点之间有两条边,
但是两楼间的距离又是处于1到D之间的,所以就规定低的指向高的为D
建图按照 下标小->下标大 权值为D
由于 大-小>=1 所以 反过来 小-大<= -1 所以下标大->下表小 权值-1
*/

#include <iostream>
#include <algorithm>
using namespace std;

#define INF 1000000000

struct Node
{
	int heigt;
	int index;
}node[1005];

struct Edge
{
	int u;
	int v;
	int w;
}edge[10050];

int dist[1005];
int sum,n;

bool cmp(Node &a,Node &b)
{
	return (a.heigt<b.heigt);
}

void Add(int u,int v,int w)
{
	edge[sum].u=u;
	edge[sum].v=v;
	edge[sum++].w=w;
}

bool Bellman_Ford(int source)
{
	int i,j;
	for(i=0;i<n;i++)
		dist[i]=INF;
	dist[source]=0;

	for(i=0;i<n-1;i++)
	{
		for(j=0;j<sum;j++)
		{
			if((dist[edge[j].u] != INF) && (dist[edge[j].u]+edge[j].w < dist[edge[j].v]))
				dist[edge[j].v] = dist[edge[j].u] + edge[j].w;
		}
	}
	for(j=0;j<sum;j++)
	{
		if((dist[edge[j].u] != INF) && (dist[edge[j].u]+edge[j].w < dist[edge[j].v]))
			return false;
	}
	return true;
}

int main()
{
	int nCase,count=0,d,i,star,end,s,e;
	cin>>nCase;
	while(nCase--)
	{
		count++;
		cin>>n>>d;
		s=INF;
		e=0;
		for(i=0;i<n;i++)
		{
			cin>>node[i].heigt;
			node[i].index=i;
			if(node[i].heigt < s)
			{
				s=node[i].heigt;
				star=i;
			}
			if(node[i].heigt > e)
			{
				e=node[i].heigt;
				end=i;
			}
		}
		
		sort(node,node+n,cmp);
		
		sum=0;
		for(i=0;i<n-1;i++)
		{
			if(node[i].index < node[i+1].index)   
				Add(node[i].index,node[i+1].index,d);
			else
				Add(node[i+1].index,node[i].index,d);
			Add(i+1,i,-1);
		}
		
		if(star > end)
			swap(star,end);
		
		if(Bellman_Ford(star))
			cout<<"Case "<<count<<": "<<dist[end]<<endl;
		else
			cout<<"Case "<<count<<": "<<-1<<endl;
	}
	return 0;
}


你可能感兴趣的:(struct,ini)