考察点:最短路径
思路:将冒险家作为图中第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;
}