poj 1062昂贵的聘礼(枚举最高地位然后最短路)

来源:互联网 发布:服务器端 java 编辑:程序博客网 时间:2024/06/05 18:43

将题意转化为图很简单,但是如何去满足一条路等级差不大于m,一开始理解错了,直接用国王的等级去做,显然错了,由于对于任何一条路径,等级的最大值一定是某一个物品主人,且n的值不大,只有100,故我们枚举最大的那个主人,每次去截取一张新的图,然后对每张图diskla就好了;

#include<iostream>

#define size 109


using namespace std;
const int inf=999999;
int dmin,dmax,m,n;
int dis[size],pos[size],use[size],s[size];
int f[size][size];


void disk()
{
int i,j,k,t,d;
memset(dis,inf,sizeof(dis));
memset(s,0,sizeof(s));
dis[0]=0;
for(i=0;i<=n;i++)
{
d=inf;
for(j=0;j<=n;j++)
{
 if(use[j]==0&&s[j]==0&&d>dis[j])
 {
d=dis[j];
k=j;
 }
}
s[k]=1;
for(t=0;t<=n;t++)
if(f[k][t]!=inf&&use[t]==0&&s[t]==0)
dis[t]=min(dis[t],dis[k]+f[k][t]);

if(k==1)
break;
}
}


void slove()
{
int i,j,ans;
ans=inf;
for(i=1;i<=n;i++)
{
memset(use,0,sizeof(use));
dmax=pos[i];dmin=dmax-m;
for(j=1;j<=n;j++)
{
              if(pos[j]>dmax||pos[j]<dmin)
              use[j]=1;//不可用
}
disk();
//cout<<dis[1]<<endl;
if(dis[1]<ans)
ans=dis[1];
}
printf("%d\n",ans);
}
 
              
              
int main()
{
int i,j,p,d,x,y,pp;
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(f,inf,sizeof(f));
memset(use,0,sizeof(use));//都为可用 
for(i=1;i<=n;i++)
{
    scanf("%d%d%d",&p,&d,&x);
    f[0][i]=p;
    pos[i]=d;


    
for(j=1;j<=x;j++)
{
   scanf("%d%d",&y,&pp);
f[y][i]=pp;
}
 
}
     
        slove();
}
return 0;
}
原创粉丝点击