1.Question:
中文题不说什么了
2.Solution:
本题的难点有两个
1.建图
2.限制
建图:
首先,我们需要明确本图G是一个有向图,我们的顶点代表庙我们的物品的编号,图采用邻接矩阵存储,我们的图中的邻接矩阵中存储我们的便宜价格这样的话,我们每个点只要在限制条件下都可以找到1点,那么我们就取到达1点的最小值当作我们的答案
限制:
本体的限制说的很明确,但是我们如何处理我们的限制确实非常的苦难,网上的大神采用了区间枚举的思路,我们对SPFA进行操作的时候,我们的松弛百年志松驰在限制区间范围的边才可以
另外,通过本体需要学会一种叫做超级源点的思路,我们的0视作超级源点,该点和其他的点之间的都有连边,连边的长度大小是我们的该点除的物品的权值,超级源点的思路非常的有用
3.Code:
/*
Problem: 1062 User: lantianheyeqi
Memory: 240K Time: 32MS
Language: C++ Result: Accepted
*/
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"
#include"cmath"
#define N 0x3f3f3f3f
int n,m;
int map[105][105];
int l[105];
void init_map()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j) map[i][j]=N;
else map[i][j]=0;
}
}
}
int SPFA(int j,int k)
{
int queue[100*100];
int head=1;
int tail=2;
bool book[105];
memset(book,0,sizeof(book));
book[0]=1;
queue[1]=0;
int dis[105];
for(int i=1;i<=n;i++) dis[i]=N;
dis[0]=0;
while(head!=tail)
{
for(int i=1;i<=n;i++)
{
if(l[i] < j || l[i] > k) continue;
if(dis[i] > dis[queue[head]]+map[queue[head]][i])
{
dis[i] = dis[queue[head]]+map[queue[head]][i];
if(book[i]==0)
{
book[i]=1;
queue[tail++]=i;
}
}
}
book[queue[head]]=0;
head++;
}
return dis[1];
}
int main()
{
scanf("%d%d",&m,&n);
init_map();
for(int i=1;i<=n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
map[0][i]=x;
l[i]=y;
for(int j=1;j<=z;j++)
{
int number,money;
scanf("%d%d",&number,&money);
map[number][i]=money;
}
}
int mink=N;
for(int i=l[1]-m;i<=l[1];i++)
{
int w=SPFA(i,i+m);
if(w<mink) mink=w;
}
printf("%d\n",mink);
return 0;
}