题目
题解思路
此题难点应该在于建图吧,认真读题抽象出单向的图,然后建立个超级源点与每个点用原价相连。
用源点跑最短路,dis[1]就是答案。
但是坑就坑在区间!
这题居然有比酋长地位高的人!!!
所以区间未必以酋长为上限,当然酋长也有可能是下限!枚举区间在加入松弛点或者进行松弛的时候加入判断,然后更新每次的最小值即可!
for (int j = lvmax - dins ;j <= lvmax + dins ; j++ )
//枚举区间下限j
{
int jmax = j + dins ; //每个区间的下限
AC代码
#include <iostream>
#include <cstring>
using namespace std;
#define inf 0x3f3f3f3f
int mp[105][105];
int dis[105];
bool vis[105];
int lev[105];
int fb(int x)
{
if (x<0)
return -x;
return x;
}
int main ()
{
memset(mp,inf ,sizeof(mp));
memset(vis,0,sizeof(vis));
int dins, n , ans ;
cin>>dins>>n;
for (int i = 1 ;i <= n ;i++)
{
int mon;
cin>>mon;
mp[0][i] = mon;
int l;
cin>>l;
lev[i] = l;
int s ;
cin>>s;
for (int k = 1 ;k <= s ; k++ )
{
int p ;
cin>>p>>mon;
mp [ p ] [ i ] = mon ;
}
}
for (int i = 0 ;i <= n ;i++ )
mp[i][i] = 0;
ans = mp [ 0 ] [ 1 ];
int lvmax = lev[1] ;
for (int j = lvmax - dins ;j <= lvmax + dins ; j++ )
{
int jmax = j + dins ;
memset(vis,0,sizeof(vis));
for (int i = 1 ;i <= n ;i++ )
dis[i] = mp [0][i] ;
vis [ 0 ] = 1;
for (int i = 0 ;i <= n ; i++ )
{
int t1 = inf ,t = 0;
for (int k = 1 ;k <= n ; k++ )
{
if (vis[k] == 0 && dis[k] < t1 && lev[k] >= j && lev[k] <= jmax )
{
t1 = dis [k] ;
t = k;
}
}
vis [ t ] = 1;
for (int k = 1 ;k <= n ; k++ )
{
if (mp[t][k] <inf && lev[k] >= j && lev[k] <= jmax )
{
dis[k] = min(dis[k] , dis[t] + mp[t][k] );
}
}
}
ans = min(dis[1],ans) ;
}
cout<<ans<<"\n";
return 0;
}