码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 1424-Salesmen(DP)

时间:2015-03-02 01:03:03      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:uva   dp   

题目大意:给出一个连通图和一个序列,求改变尽量少的序列中的元素,使得相邻两个元素相同或在图中相邻。


a[i][j]=1表示i和j相邻,a[i][j]=0表示i和j不相邻。b[i]表示序列中第i个数。

用d[i][j]表示前i个数且第i个数为元素j时的最少改变数量,由d[i-1][u]推来。其中j和u相同或相邻。


状态转移方程:d[i][j]=min { d[i-1][u]+k }(a[u][j]=1,u==b[i]时k=0,u!=b[i]时k=1)


#include<stdio.h>
#include<stdlib.h>
int a[110][110];
int b[210];
int d[210][110];
int main(void)
{
	int i,j,u,v,p,n,m,pi,qi,min,minp;
	scanf("%d",&pi);
	for(qi=0;qi<pi;qi++)
	{
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				a[i][j]=0;
			}
		}
		for(i=1;i<=n;i++)
		{
			a[i][i]=1;
		}
		for(i=1;i<=m;i++)
		{
			scanf("%d%d",&u,&v);
			a[u][v]=a[v][u]=1;
		}
		scanf("%d",&p);
		for(i=1;i<=p;i++)
		{
			scanf("%d",&b[i]);
		}
		for(j=1;j<=n;j++)
		{
			if(j!=b[1])
			{
				d[1][j]=1;
			}
			else
			{
				d[1][j]=0;
			}
		}
		for(i=2;i<=p;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(b[i]==j)
				{
					minp=1000000000;
					for(u=1;u<=n;u++)
					{
						if((a[u][j]==1)&&(d[i-1][u]<minp))
						{
							minp=d[i-1][u];
						}
					}
					d[i][j]=minp;
				}
				else
				{
					minp=1000000000;
					for(u=1;u<=n;u++)
					{
						if((a[u][j]==1)&&(d[i-1][u]+1<minp))
						{
							minp=d[i-1][u]+1;
						}
					}
					d[i][j]=minp;
				}
			}
		}
		min=d[p][1];
		for(j=2;j<=n;j++)
		{
			if(d[p][j]<min)
			{
				min=d[p][j];
			}
		}
		printf("%d\n",min);
	}
	return 0;
}


UVA 1424-Salesmen(DP)

标签:uva   dp   

原文地址:http://blog.csdn.net/dilemma729/article/details/44009071

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!