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;
} 
京公网安备 11010502036488号