[NC22600]Rinne Loves Dynamic Graph
一、题目
二、思路
这题最主要的是看有没有发现函数的性质,这个函数推两步就会发现
\[f(x) = \frac{1}{1 - x} \tag{1$'$}
\]
\[f(f(x)) = \frac{x}{x - 1} \tag{2$'$}
\]
\[f(f(f(x))) = x \tag{3$'$}
\]
变化三次后边的权值又变回原本的权值
所以直接建分层图或者用最短路dp都可以
我这里用的是分层图
三、代码
#include<bits/stdc++.h>
using namespace std;
const int N = 300100 * 2 * 3;
const double INF = 0x3f3f3f3f3f3f3f3f;
typedef pair<double, int> PII;
int n, m;
int h[N], e[N], ne[N], idx;
double w[N];
bool st[N];
double dist[N];
void add(int a, int b, double c){
w[idx] = c;
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
void dijkstra(){
for (int i = 1; i <= N; i ++) dist[i] = INF;
//memset(dist, INF, sizeof dist);
//cout << dist[n] << endl;
dist[1] = 0;
priority_queue<PII, vector<PII>, greater<PII> > heap;
heap.push({0, 1});
while(heap.size()){
PII k = heap.top();
heap.pop();
int ver = k.second;
double distance = k.first;
if(st[ver]) continue;
st[ver] = true;
for(int i = h[ver]; i != -1; i = ne[i]){
int j = e[i];
if(dist[j] > distance + w[i]){
dist[j] = distance + w[i];
//cout << w[i] << endl;
heap.push({dist[j], j});
}
}
}
}
int main(){
cin >> n >> m;
int a, b;
double c;
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i ++){
cin >> a >> b;
cin >> c;
add(a, b + n, abs(c));
add(b, a + n, abs(c));
c = (1.0 / (1 - c));
//cout << c << endl;
add(a + n, b + 2 * n, abs(c));
add(b + n, a + 2 * n, abs(c));
c = (1.0 / (1 - c));
//cout << c << endl;
add(a + 2 * n, b, abs(c));
add(b + 2 * n, a, abs(c));
}
dijkstra();
double ans = min(dist[n], min(dist[2 * n], dist[3 * n]));
//cout << dist[3 * n] << endl;
if(ans == 0x3f3f3f3f3f3f3f3f) cout << "-1" << endl;
else printf("%.3lf\n", ans);
return 0;
}


浙公网安备 33010602011771号