题目连接在此
变法最短路,附加等级范围枚举
总体来说就是枚举登记范围,然后用spfa跑
ac代码如下
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
vector< vector<int> > T;
int M, N;
int spfa(int b, int e)
{
int P[105];
for(int i=1; i<=N; ++i) P[i] = 1<<20;
P[1] = T[0][1];
int inQueue[105];
memset(inQueue,0,sizeof(inQueue));
queue<vector<int> > findW;
findW.push(T[0]);
inQueue[1] = 1;
while(!findW.empty())
{
vector<int> u = findW.front();
inQueue[u[0]] = 0;
findW.pop();
//cout<<u[0]<<endl;
for(int i=0; i<u[3]; ++i)
{
if(b<=T[u[4+2*i]-1][2]&&T[u[4+2*i]-1][2]<=e) //连通判断
{
if(P[u[4+2*i]]>P[u[0]]-u[1]+u[4+2*i+1]+T[u[4+2*i]-1][1])
{
P[u[4+2*i]] = P[u[0]]-u[1]+u[4+2*i+1]+T[u[4+2*i]-1][1];
if(inQueue[u[4+2*i]]==0)
{
findW.push(T[u[4+2*i]-1]);
inQueue[u[4+2*i]]=1;
}
}
}
}
}
int MinN = 1<<20;
for(int i=1; i<=N; ++i)
if(P[i]<MinN) MinN = P[i];
return MinN;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>M>>N)
{
T.clear();
for(int i=1; i<=N; ++i)
{
int p, x, l;
cin>>p>>l>>x;
vector<int> temp;
temp.push_back(i), temp.push_back(p), temp.push_back(l), temp.push_back(x);
for(int j=1; j<=x; ++j)
{
int t, v;
cin>>t>>v;
temp.push_back(t), temp.push_back(v);
}
T.push_back(temp);
temp.clear();
}
//SPFA Algorithm
int MinN = 1<<20;
for(int i=T[0][2]-M; i<=T[0][2]; ++i)
{
int temp = spfa(i,i+M);
if(temp<MinN) MinN = temp;
}
cout<<MinN<<endl;
}
return 0;
}