[ZJOI2006]物流运输
[ZJOI2006]物流运输
https://ac.nowcoder.com/acm/problem/20469
做法:spfa+dp
思路:
- 1.用邻接表连双向边
- 2.st[i][j]存i码头第j天不工作
- 3.cost[i][j]表示第i天到第j天的花费,spfa来求值
- 4.dp求最小的总成本
代码
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mp(aa,bb) make_pair(aa,bb) #define _for(i,b) for(int i=(0);i<(b);i++) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define per(i,b,a) for(int i=(b);i>=(a);i--) #define mst(abc,bca) memset(abc,bca,sizeof abc) #define X first #define Y second #define lowbit(a) (a&(-a)) typedef long long ll; typedef pair<int,int> pii; typedef unsigned long long ull; typedef long double ld; const int N=110; const int INF=0x3f3f3f3f; const int mod=1e9+7; const double eps=1e-6; const double PI=acos(-1.0); struct node{ int to; ll w; }; int n,m,k,e; vector<node> g[25]; bool st[25][110],vis[25]; ll dis[25],cost[110][110],dp[110]; queue<int> q; ll spfa(int l,int r){ for(int i=1;i<=m;i++) dis[i]=INF,vis[i]=0; dis[1]=0; q.push(1); vis[1]=true; while(q.size()){ int t=q.front();q.pop(); vis[t]=false; for(auto x:g[t]){ bool flag=0; int j=x.to; for(int i=l;i<=r;i++){ if(st[j][i]){ flag=1;break; } } if(flag) continue; if(dis[j]>dis[t]+x.w){ dis[j]=dis[t]+x.w; if(!vis[j]){ q.push(j); vis[j]=true; } } } } return dis[m]; } void solve(){ cin>>n>>m>>k>>e; _for(i,e){ int x,y,w; cin>>x>>y>>w; g[x].pb({y,w}); g[y].pb({x,w}); } int d;cin>>d; _for(i,d){ int p,a,b;cin>>p>>a>>b; rep(j,a,b) st[p][j]=1; } rep(i,1,n) rep(j,1,n){ cost[i][j]=spfa(i,j); } rep(i,1,n) dp[i]=INF; rep(i,1,n){ dp[i]=cost[1][i]*i; for(int j=1;j<i;j++){ dp[i]=min(dp[i],dp[j]+k+cost[j+1][i]*(i-j)); } } cout<<dp[n]<<"\n"; } int main(){ ios::sync_with_stdio(0); cin.tie(0); #ifdef DEBUG freopen("F:/laji/1.in", "r", stdin); // freopen("F:/laji/2.out", "w", stdout); #endif // int t;cin>>t;while(t--) solve(); return 0; }
牛客每日一题 文章被收录于专栏
水