poj 1062

题意上有一点要注意:在任何一条路径上,任何两点的等级之差都必须在限制之内。比如说:abc的等级分别为321,限制为1的话。能和ab交易就不能和c交易了,因为ac超出限制。同样,bc能交易就不能和a交易了,因为ac任然超出限制。根据题意将每种物品看成每个顶点,优惠价格看成边,便构成一有向图,然后可以用Dijkstra求解。因为有等级限制,求一次Dijkstra是不行的。我看了网上大牛的思想:枚举0~L的每一种限制i,除去不在区间[rand[1]-i,rand[i]+m-i](rand[1]为酋长的等级)的顶点,然后Dijkstra,取其中最小的。

#include<iostream>
#include<vector>
using namespace std;
#define MAX_INT 1234567890
struct edge
{
	int v;
	int value;
};
struct good
{
	int price;
	int grade;
};
good head[101];
vector <edge> map[101];
int dist[101],visit[101];
bool flag[101];
int dijkstra(int n)
{
	int i,j,k,min;
    for(i=1;i<=n;i++)
		dist[i]=MAX_INT;
	for(i=0;i<map[1].size();i++)
		if(flag[map[1][i].v])
			dist[map[1][i].v]=map[1][i].value;
	visit[1]=1;
	for(i=1;i<n;i++)
	{
		min=MAX_INT; k=0;
		for(j=1;j<=n;j++)
		    if(!visit[j] && dist[j]<min)
			{
				min=dist[j];
				k=j;
			}
		visit[k]=1; 
		if(k==0) break;
		for(j=0;j<map[k].size();j++)
		{
			if(!visit[map[k][j].v] && flag[map[k][j].v])
			{
				if(dist[map[k][j].v]>dist[k]+map[k][j].value)
					dist[map[k][j].v]=dist[k]+map[k][j].value;
			}
		}
	}
	min=MAX_INT; dist[1]=0;
	for(i=1;i<=n;i++)
	{
		if(min>dist[i]+head[i].price)
			min=dist[i]+head[i].price;
	}
	return min;
}
int main()
{
	int i,j,m,n,k,gap,min;
	edge e;
	while(cin>>gap>>n)
	{
		for(i=1;i<=n;i++)
		{
			cin>>head[i].price>>head[i].grade>>m;
			for(j=0;j<m;j++)
			{
				cin>>e.v>>e.value;
				map[i].push_back(e);
			}
		}
		min=MAX_INT;
		for(i=0;i<=gap;i++)
		{
			memset(visit,0,sizeof(visit));
			for(j=1;j<=n;j++)
				if(head[j].grade>=head[1].grade-i && head[j].grade<=head[1].grade+gap-i)
					flag[j]=true;
				else
					flag[j]=false;
			k=dijkstra(n);
			if(min>k) min=k;
		}
		cout<<min<<endl;
		for(i=1;i<=n;i++)
			map[i].clear();
	}
	return 0;
}

看了大牛的思想任然感觉有点模糊,所以我有用dfs做了一遍,这样做简单一点,也可以AC

#include<iostream>
#include<cstring>
using  namespace std;
#define MAX_INT 1234567890
int edge[101][101],price[101],rank[101],visit[101],min1,n,gap;
int dfs(int i,int value,int min_rank,int max_rank)
{
	int j;
	visit[i]=1;
	min1=(min1>value+price[i])? value+price[i]:min1;
	for(j=1;j<=n;j++)
	{
		if(!visit[j] && edge[i][j])
		{
			if(rank[j]<min_rank && max_rank-rank[j]<=gap)
				dfs(j,value+edge[i][j],rank[j],max_rank);
			else if(rank[j]>max_rank && rank[j]-min_rank<=gap)
			    dfs(j,value+edge[i][j],min_rank,rank[j]);
			else if(rank[j]>=min_rank && rank[j]<=max_rank)
				dfs(j,value+edge[i][j],min_rank,max_rank);
		}
	}
	visit[i]=0;
	return 0;
}
int main()
{
	int i,j,s,t,num;
	while(cin>>gap>>n)
	{
	    for(i=1;i<=n;i++)
		{
			cin>>price[i]>>rank[i]>>num;
			for(j=0;j<num;j++)
			{
				cin>>s>>t;
				edge[i][s]=t;
			}
		}
		min1=MAX_INT;
		memset(visit,0,sizeof(visit));
		dfs(1,0,rank[1],rank[1]);
		cout<<min1<<endl;
	}
	return 0;
}
posted @ 2011-08-15 08:27  书山有路,学海无涯  阅读(1454)  评论(0编辑  收藏  举报