1. 程式人生 > 其它 >[NC22600]Rinne Loves Dynamic Graph

[NC22600]Rinne Loves Dynamic Graph

一、題目

NC22600

二、思路

這題最主要的是看有沒有發現函式的性質,這個函式推兩步就會發現

\[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;
}