903. 昂贵的聘礼(acwing)
单源最短路
903. 昂贵的聘礼
题目大意:
要拿到点i的物品需要vali的价值。但是点i会在已经拿到点j物品的时候打折。而且每个点都有一个地位,地位差直接或者间接超过m的不能交易。问拿到点1物品的最小花费。
思路和代码:
我一开始想处理路径差值的方法是这样的:
$$
abs(rnk_i - rnk_1)<=m
$$
但是错就错在这里,用绝对值的话,路径上可能有两个点的地位差值最坏是2*m。所以还是需要去枚举长度为m的地位区间。
我的思路是从点1出发,求出到点i的最短花费。
ll n , m , k ;
struct edge{
ll to , len ;
};
vct eg[110] ;
ll val[110] , rnk[110] ;
ll spfa(ll dw , ll up){
vct ds(n + 1 , INF) ;
vct inq(n + 1 , 0) ;
inq[1] = 1 ;
ds[1] = val[1] ;
queue q ;
q.push(1) ;
while(q.size()){
ll idx = q.front() ;
q.pop() ;
inq[idx] = 0 ;
for(auto x : eg[idx]){
if(rnk[x.to] < dw || up < rnk[x.to]) continue ;
ll ifgoto = ds[idx] + x.len + val[x.to] - val[idx] ;
if(ds[x.to] > ifgoto){
ds[x.to] = ifgoto ;
if(inq[x.to]) continue ;
q.push(x.to) ;
inq[x.to] = 1 ;
}
}
}
ll ans = INF ;
rep(i , 1 , n)
if(abs(rnk[i] - rnk[1]) <= m)
ans = min(ans , ds[i]) ;
return ans ;
}
void solve(){
cin >> m >> n ;
rep(i , 1 , n){
ll num ;
cin >> val[i] >> rnk[i] >> num ;
rep(j , 1 , num){
ll to , prs ;
cin >> to >> prs ;
//if(abs(rnk[i] - rnk[1]) > m) continue ;
eg[i].pb({to , prs}) ;
//eg[to].pb({i , prs}) ;
}
}
ll ans = INF ;
rep(i , rnk[1] - m , rnk[1]) ans = min(ans , spfa(i , i + m)) ;
cout << ans << "\n" ;
}//code_by_tyrii
再就是官方的题解:
有两个要点:反向建图+超级源点
先将所有点和点0链接起来,边权就是点i的权值。再以点0为起点做其他所有点的最短路。
ll n , m , k ;
ll val[N] , rnk[N] ;
struct edge{
ll to , len ;
};
vct eg[N] ;
ll dij(ll dw , ll up){
vct ds(n + 1 , INF) ;
vct vis(n + 1 , 0) ;
ds[0] = 0 ;
rep(i , 1 , n){
ll now = -1 ;
rep(j , 0 , n)
if(!vis[j] && (now == -1 || ds[j] < ds[now])) now = j ;
vis[now] = 1 ;
for(auto x : eg[now]) {
if(rnk[x.to] > up || rnk[x.to] < dw) continue ;
ds[x.to] = min(ds[x.to] , ds[now] + x.len) ;
}
}
return ds[1] ;
}
void solve(){
cin >> m >> n ;
rep(i , 1 , n){
ll num ;
cin >> val[i] >> rnk[i] >> num ;
eg[0].pb({i , val[i]}) ;//超级源点
while(num -- ){
ll u , w ;
cin >> u >> w ;
eg[u].pb({i , w}) ;//反向建图
}
}
ll ans = INF ;
rep(i , rnk[1] - m , rnk[1])
ans = min(ans , dij(i , i + m)) ;
cout << ans << "\n" ;
}//code_by_tyrii
小结:
这题如果反向建图,则要把所有点到点1的最短路求出来(多源最短路?)。设置一个超级源点0可以将其变成一个单源最短路的问题。