Before the Beginning
转载请将本段放在文章开头显眼处,如有二次创作请标明。
原文链接:https://www.codein.icu/nowcoderweekly16/
显然变动函数是一个周期函数,相信大家都做过类似的数学题。
设经过边数为 ,边权为 ,将 代入即可求得当时边权。
随后就是经典的分层图、图上dp问题。
设计状态为,到达 点,经过边数模三结果为 ,跑个最短路就行了。 代表上述状态的最小距离。
#include <cstdio> #include <queue> #include <algorithm> #include <ctype.h> const int bufSize = 1e6; #define DEBUG inline char nc() { #ifdef DEBUG return getchar(); #endif static char buf[bufSize], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, bufSize, stdin), p1 == p2) ? EOF : *p1++; } inline void read(char *s) { static char c; for (; !isalpha(c); c = nc()); for (; isalpha(c); c = nc()) *s++ = c; *s = '\0'; } template<typename T> inline T read(T &r) { static char c; static int flag; flag = 1, r = 0; for (c = nc(); !isdigit(c); c = nc()) if (c == '-') flag = -1; for (; isdigit(c); c = nc()) r = r * 10 + c - 48; return r *= flag; } const int maxn = 1e6 + 100; const int maxm = 1e6 + 100; int n,m; template<typename T> inline T abs(const T &a){return a > 0 ? a : -a;} inline double getdis(int x,int t) { if(t == 0) return abs(1.0 * x); else if(t == 1) return abs(1.0 / (1.0 - x)); else return abs(1.0 - 1.0 / x); } struct node { int to,next,val; }E[maxm]; int head[maxn]; inline void add(const int &x,const int &y,const int &val) { static int tot = 0; E[++tot].next = head[x],E[tot].to = y,E[tot].val = val,head[x] = tot; } double dis[maxn][5]; using namespace std; struct aaa { int id,t; double dis; bool operator<(const aaa &b) const{return dis > b.dis;} }; priority_queue<aaa> q; bool vis[maxn][5]; inline void dij() { for (int i = 1; i <= n; ++i) dis[i][0] = dis[i][1] = dis[i][2] = 1e30; dis[1][0] = 0; aaa t; t.id = 1,t.t = 0,t.dis = dis[1][0]; q.push(t); while(!q.empty()) { int u = q.top().id; int t = q.top().t; q.pop(); if(vis[u][t]) continue; vis[u][t] = 1; for (int p = head[u]; p; p = E[p].next) { int v = E[p].to; int nt = (t + 1) % 3; double nv = getdis(E[p].val,t); if(vis[v][nt]) continue; if(dis[v][nt] > dis[u][t] + nv) { dis[v][nt] = dis[u][t] + nv; aaa ne; ne.id = v,ne.t = nt; ne.dis = dis[v][nt]; q.push(ne); } } } } int main() { read(n),read(m); while(m--) { int a,b,c; read(a),read(b),read(c); add(a,b,c),add(b,a,c); } dij(); int viss = (vis[n][0] | vis[n][1] | vis[n][2]); double anss = std::min(dis[n][0],dis[n][1]); anss = std::min(anss,dis[n][2]); if(!viss) puts("-1"); else printf("%.3f",anss); return 0; }