題解 P5837 【[USACO19DEC]Milk Pumping】


這題其實想法挺簡單的,因為他只需要簡單的把每個點的花費和流量用dp記下來就好了

1.怎么記:

首先考慮dp的狀態。由於所在的點和流量都要記,所以dp開二維,一維記所在的點,另一維記去哪

//dp[i][j] ==> i 是現在所在的點,j是流量

2.從哪開始

看題

3.轉移方法

//dp[要去的點][現在的流量和要去的流量的最小值] = dp[現在的點][現在的流量]+去的花費

4.輸出

在終點,對於每個能到達的流量,最大值就是花費/流量

dijkstra代碼:

#include <iostream> #include <algorithm> #include <math.h> #include <cstring> #include <queue> #include <fstream> using namespace std; #define pp pair<long long,long long> #define mp make_pair long long maxi = 0, n,m, tot=0,head[100001]; struct Edge{ long long to, next,cost,flow; }edge[100001]; void add(long long x, long long y,long long co, long long fl){ edge[tot].to = y; edge[tot].cost = co; edge[tot].flow = fl; edge[tot].next = head[x]; head[x] = tot; } long long dp[1001][1001]; void dij(long long a, long long b){ // dijkstra dp[a][b] = 0; queue<pp> q; q.push(mp(a,b)); while(!q.empty()){ long long qf = q.front().first; long long qs = q.front().second; q.pop(); for(long long i=head[qf];i;i=edge[i].next){ long long t = edge[i].to, flo = edge[i].flow; if (dp[t][min(qs,flo)]>dp[qf][qs]+edge[i].cost){ dp[t][min(qs,flo)] = dp[qf][qs]+edge[i].cost; //上面講的轉移 q.push(mp(t,min(qs,flo))); } } } } int main(){ // setIO("pump"); cin >> n >> m; for (long long i=0;i<m;i++){ long long a,b,c,d; cin >> a >> b >> c >> d; add(a,a,c,d); add(b,b,c,d); } memset(dp,0x3f3f3f3f,sizeof(dp)); dij(1,1000); for (long long i=1;i<1000;i++){ if (dp[n][i]>1e9) continue; //越界不? long long num = floor((double)(i*1e6)/(double)dp[n][i]); // 不越界計算 maxi = max(maxi,num); } cout << maxi; } 

spfa:

#include <iostream> #include <algorithm> #include <math.h> #include <cstring> #include <queue> #include <fstream> using namespace std; #define pp pair<long long,long long> #define mp make_pair long long maxi = 0, n,m, tot=0,head[100001]; struct Edge{ long long to, next,cost,flow; }edge[100001]; void add(long long x, long long y,long long co, long long fl){ edge[tot].to = y; edge[tot].cost = co; edge[tot].flow = fl; edge[tot].next = head[x]; head[x] = tot; } bool vis[1001][1001]; long long dp[1001][1001]; void spfa(long long a, long long b){ dp[a][b] = 0; vis[a][b] = true; queue<pp> q; q.push(mp(a,b)); while(!q.empty()){ long long qf = q.front().first; long long qs = q.front().second; vis[qf][qs] = false; q.pop(); for(long long i=head[qf];i;i=edge[i].next){ long long t = edge[i].to, flo = edge[i].flow; if (dp[t][min(qs,flo)]>dp[qf][qs]+edge[i].cost){ dp[t][min(qs,flo)] = dp[qf][qs]+edge[i].cost; if (!vis[t][min(qs,flo)]) {vis[t][min(qs,flo)] = true;q.push(mp(t,min(qs,flo)));} } } } } int main(){ // setIO("pump"); cin >> n >> m; for (long long i=0;i<m;i++){ long long a,b,c,d; cin >> a >> b >> c >> d; add(a,a,c,d); add(b,b,c,d); } memset(dp,0x3f3f3f3f,sizeof(dp)); spfa(1,1000); for (long long i=1;i<1000;i++){ if (dp[n][i]>1e9) continue; long long num = floor((double)(i*1e6)/(double)dp[n][i]); maxi = max(maxi,num); } cout << maxi; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM