1062终于给出来了

来源:互联网 发布:原油库存数据公布 编辑:程序博客网 时间:2024/05/11 15:34

http://acm.pku.edu.cn/JudgeOnline/problem?id=1062

 

用DIJ算法,注意到等级的不同,等级差为M,那么一次设M+1个区间,使酋长都在之内,再依次独立的计算最小值,很明显可以用一个for循环;

 

 

用结构体存每一位人的物品的钱,用t[Max]存每一为的等级。

具体算法如下

 

#include<iostream>
#include<cmath>
using namespace std;

const int Max=100;
#define INF 10000000
struct w
{
 int statu;
 int m;
}s[Max];
int M;

int b[Max][Max];
int t[Max];
void DIJ(int N);

int main()
{
 freopen("in.txt","r",stdin);
 int N,P,L,X,i,j,xx,yy;
 cin>>M>>N;

 for( i=0; i<N; i++)
 {
  s[i].m=0;
  for( j=0; j<N; j++)
   b[i][j]=INF;
 }
 for( i=0; i<N; i++)
 {
  cin>>P>>L>>X;
  s[i].m=P;
  t[i]=L;
  s[i].statu =L;
  for( j=0; j<X; j++)
  {
   cin>>xx>>yy;
   b[i][xx-1]=yy;
  }


 }
 
 DIJ(N);


 return 0;
}


void DIJ(int N)
{
 int i,v,w,min,j,mt,k,temp[Max][Max],end(s[0].m);//end最大唯没有换的时候
 int final[Max]={0};
 int d[Max];
 final[0]=1;
 
 
 mt=t[0];//mt为酋长的等级
 
 for(k=0; k<=M; k++)//每种范围都比较过去
 {
  for( i=0; i<N; i++)
   for( j=0; j<N; j++)
    temp[i][j]=b[i][j];
  for( i=1; i<N; i++)
   if(t[i]<mt-M+k||t[i]>mt+k)//不再范围内
   {
    for( j=0; j<N; j++)//所有和i有关的给点都删去
    {
     temp[i][j]=INF;
     temp[j][i]=INF;
    }
   }

  for( v=0; v<N; v++)
  {
   
   d[v]=temp[0][v];//之前些为b[0][v]给wa了n次
   
  
   final[v]=0;
  }
  
  v=0;
  final[v]=1;
  d[v]=INF;
  for( i=1; i<N; i++)
  {
   min=100000;
   for( w=0; w<N; w++)
    if( !final[w]&&d[w]<min) 
     {v=w;min=d[w];}
     final[v]=1;
     for( w=0; w<N; w++)
      if(!final[w]&&(min+temp[v][w]<d[w]))
      {
       d[w]=min+temp[v][w];
      }
  }
  for( i=0; i<N; i++)
 
   for( j=0; j<N; j++)
    temp[i][j]=0;
 
 //cout<<min<<endl;
 
  min=INF;
  for( i=0; i<N; i++)
   if((d[i]+s[i].m)<min&&d[i]!=INF)
   {
    min=d[i]+s[i].m;
    j=i;
   }
   if(min<end)
    end=min;
 }  
 cout<<end<<endl;
}

原创粉丝点击