日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[NOI2019]回家路线

發布時間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [NOI2019]回家路线 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LOJ3156

題面就不放了 , 放一下數據范圍 .

看到 \(n<=2000,m<=4000\) 就想到直接 \(dfs\) 到底 , 居然就過了前 \(4\)個 樣例 , 最后一個要 \(2s\) . 后來寫了 \(A=B=0\)\(5\) 分 , 我知道寫的是錯的 , 還是交了以下這份代碼 . ( LOJ 數據應該是官方數據 ) 得分 \(70\) .

晚上到 LOJ 上一測 , 發現如果直接跑我的暴力有 \(80\) 分 , 又到 \(AC\) 記錄里面隨便看了一篇比較優秀的 , 改在后面 .

#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cassert> #include<queue> #define debug(...) fprintf(stderr,__VA_ARGS__) #define Debug(x) cout<<#x<<"="<<x<<endl using namespace std; typedef long long LL; const int INF=1e9+7; inline LL read(){register LL x=0,f=1;register char c=getchar();while(c<48||c>57){if(c=='-')f=-1;c=getchar();}while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();return f*x; }const int N=100005; const int M=200005;struct Edge{int v,s,t,nxt; }e[M]; int first[N],Ecnt=0; inline void Add_edge(int u,int v,int s,int t){e[++Ecnt]=(Edge){v,s,t,first[u]};first[u]=Ecnt; }int n, m, A, B, C;inline LL calc(int x){return 1ll * A * x * x + 1ll * B * x + C; }namespace baoli{LL ans = INF;inline void dfs(int u, int time, LL cost){if(u == n){ans = min(ans, cost + time);}for(int i = first[u]; i; i = e[i].nxt){int v = e[i].v, s = e[i].s, t = e[i].t;if(s < time) continue;dfs(v, t, cost + calc(s - time));}}inline void main(){dfs(1, 0, 0);printf("%lld\n", ans);exit(0);} };namespace Subtask1{ // A == 0 && B == 0int dis[N], time[N];queue <int> q;LL ans = INF;inline void Return(LL ans){printf("%lld\n", ans);exit(0);}inline void main(){q.push(1);memset(dis, 0x3f, sizeof dis);dis[1] = 0;while(!q.empty()){int u = q.front(); q.pop();for(int i = first[u]; i; i = e[i].nxt){int v = e[i].v;if(time[u] > e[i].s) continue;if(dis[u] + 1 < dis[v]){dis[v] = dis[u] + 1;time[v] = e[i].t;q.push(v);}if(v == n) ans = min(ans, 1ll * (dis[u] + 1 + 1) * C + e[i].t);}}Return(ans);assert(false);}/*inline void main(){q.push((Node){1, 0, 0});while(!q.empty()){int u = q.front().x, d = q.front().dis, t = q.front().time; q.pop();for(int i = first[u]; i; i = e[i].nxt){int v = e[i].v;if(e[i].t < t) continue;if(}}}*/ };int main(){ #ifndef filefreopen("route.in","r",stdin);freopen("route.out","w",stdout); #endifn = read(), m = read(), A = read(), B = read(), C = read();for(register int i = 1; i <= m; ++i){register int x = read(), y = read(), p = read(), q = read();Add_edge(x, y, p, q);}if(n <= 2000 && m <= 4000) baoli::main();if(A == 0 && B == 0) Subtask1::main(); }

LOJ上的一份AC代碼

我沒注意到時間 \(q<=1000\) , 這樣的話 \(O(nq)=O(1e8)\) 應該可以卡過?
直接 \(dp\) 有人得了 95分 . 把列車 按照時間排序 , 再依次更新 , 這樣 \(1e8\) 就跑不滿 , 直接就過了 . 可以用 \(vector\) 存狀態 .
對于這個數據范圍就當 \(O(nq)\) 是正解好了 .

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #define debug(...) fprintf(stderr,__VA_ARGS__) #define Debug(x) cout<<#x<<"="<<x<<endl using namespace std; typedef long long LL; const LL INF=1e18+7; inline LL read(){register LL x=0,f=1;register char c=getchar();while(c<48||c>57){if(c=='-')f=-1;c=getchar();}while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();return f*x; }const int N = 1e5 + 5; const int M = 2e5 + 5;struct Node{int x, y, p, q; }a[M]; inline bool cmp1(Node a, Node b){if(a.p == b.p) return a.q < b.q;return a.p < b.p; }vector <LL> f[N]; vector <int> t[N]; int n, m, A, B, C;inline LL calc(int x){return 1ll * A * x * x + 1ll * B * x + C; }int main(){ #ifndef filefreopen("route.in","r",stdin);freopen("route.out","w",stdout); #endifn = read(), m = read(), A = read(), B = read(), C = read();for(int i = 1; i <= m; ++i){a[i].x = read(), a[i].y = read(), a[i].p = read(), a[i].q = read();}sort(a + 1, a + m + 1, cmp1);f[1].push_back(0), t[1].push_back(0);for(int i = 1; i <= m; ++i){int x = a[i].x, y = a[i].y, p = a[i].p, q = a[i].q;int tt = -1;for(int j = 0; j < t[y].size(); ++j)if(t[y][j] == q) {tt = j; break;}for(int j = 0; j < f[x].size(); ++j){if(t[x][j] > p) continue;int len = p - t[x][j];if(tt == -1){f[y].push_back(f[x][j] + calc(len));t[y].push_back(q);tt = f[y].size() - 1;}else if(f[x][j] + calc(len) < f[y][tt]){f[y][tt] = f[x][j] + calc(len);}}}LL ans = INF;for(int i = 0; i < f[n].size(); ++i)ans = min(ans, f[n][i] + t[n][i]);printf("%lld\n", ans); }

轉載于:https://www.cnblogs.com/lizehon/p/11197337.html

總結

以上是生活随笔為你收集整理的[NOI2019]回家路线的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。