POJ1062

17 篇文章 0 订阅

考察点:最短路径

思路:将冒险家作为图中第0个点,女人做为第一个点,剩余物品是其他点。先构造一个总图,然后根据等级来筛选符合标准的子图,在每一个子图中搜索最短路径,得到的最终最短路径即为所求。

提交情况:提交2次,因为根据权限来筛选的合适子图的代码写错了,少了等于号

收获:熟悉了邻接表建立图的方法和BF算法求最短路径。

代码的确很乱,导致了调试很麻烦,也没分函数,直接啪啪啪的敲上去了,最后因为那个等号的问题调整了很长的时间。

以后还是要学会分函数

另外,排序是不必要的,是我第一种方法才用到,这里排不排序一样了

#include<iostream>
const int MAX=103;
using namespace std;


int countThings=0;
struct node
{
	int num;
	int weight;
	node* next;
};
struct thing
{
	int d;
	int num;
};

void insert(node* myv[MAX],node* p,int pos)
{
		node* p1=myv[pos];
		if(p1==NULL)
		{
			myv[pos]=p;	
		}
		else
		{
			while(p1->next!=NULL)
			{
				p1=p1->next;
			}
			p1->next=p;
		}
}

void swap(thing* t[200],int q,int w)
{
	thing* tt=t[q];
	t[q]=t[w];
	t[w]=tt;
}



int main()
{
	int m,vc;
	node* v[MAX];
	node* tv[MAX];
//	int degree[1000];
	thing* things[200];
	thing* tthing;
	int qdegree;
	cin>>m>>vc;
	int i,j,k;
	int s,e,w,ts,tw;
	int tdegree;//某物品的等级
	int n;
	node* p;
	node* tp;


	for(i=0;i<MAX;i++)
	{
		v[i]=NULL;
		tv[i]=NULL;
	}
	//输入数据 构造总图
	for(i=1;i<=vc;i++)
	{

		cin>>w>>tdegree>>n;
		if(i==1)
		{
			qdegree=tdegree;
		}
		tthing=new thing;
		tthing->d=tdegree;
		tthing->num=i;
		things[countThings]=tthing;
		countThings++;

	//	p=v[0];
		tp=new node;
		tp->num=i;
		tp->weight=w;
		tp->next=NULL;
		insert(v,tp,0);
		for(j=0;j<n;j++)
		{
			cin>>ts>>tw;
			tp=new node;
			tp->next=NULL;
			tp->num=i;
			tp->weight=tw;
			insert(v,tp,ts);
		}
	}
	int min;
	int minI;
	//排序
	for(i=0;i<vc;i++)
	{
		minI=i;
		min=things[i]->d;
		for(j=i;j<vc;j++)
		{
			if(things[j]->d<min)
			{
				min=things[j]->d;
				minI=j;
			}
		}
		swap(things,i,minI);
	}

	int sdegree;

	min=9999999;
	int tmin;
	
	//最短路
	int ti,tj,tk;
	int dist[MAX];
	int change;

	for(i=0;i<=m;i++)
	{
		for(k=0;k<MAX;k++)
		{
			tv[k]=NULL;
		}
		for(j=0;j<vc;j++)
		{
			if(things[j]->d>=qdegree-m+i&&things[j]->d<=qdegree+i)//筛选子图
			{
				tv[things[j]->num]=v[things[j]->num];
			}	
		}
		tv[0]=v[0];
		for(ti=0;ti<MAX;ti++)
		{
		dist[ti]=999999;
		}
		dist[0]=0;
		node* pn;
		for(ti=0;ti<vc;ti++)
		{
			
			for(tj=0;tj<vc+1;tj++)
			{
				pn=tv[tj];
				while(pn!=NULL)
				{
					if(dist[pn->num]>dist[tj]+pn->weight)
					{
						dist[pn->num]=dist[tj]+pn->weight;
					}
					pn=pn->next;
				}
			}
		}
		if(min>dist[1])
		{
			min=dist[1];
		}
	}
	
	cout<<min;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值