노이즈의 증폭이 최소가 되는 경로를 찾는 문제이다. 책에는 "노이즈 c 는 언제나 1 이상 3 이하의 실수입니다" 라고 나와있다고 한다.
음.. 이게 딱히 문제는 없을 거 같지만, c의 범위를 몰라서 정답의 범위를 모르기때문에, 무한대값(INF)를 설정을 못한다. INF=987654321 로 설정하면 오답이 나온다.
987654321 보다 큰 경로만 남아있을 때, 방문하지 않은 정점들은 987654321 일테니 탐색하지 않아버린다.
방문한 노드와 방문하지 않은 노드를 따로 구분해야한다. 다익스트라에서는 음수인 가중치가 없을테니 방문하지 않은 노드를 -1 로 해도 될거같다.
#include <bits/stdc++.h>
using namespace std;
typedef long long lld;
struct edge {
int next;
double weight;
bool operator < (const edge& p) const {
if(abs(weight - p.weight) < 1e-9) return next < p.next;
return weight > p.weight;
}
};
vector<edge> adj[10001];
bool visited[10001];
int main(){
int T;
scanf("%d", &T);
while(T--){
int n, m;
scanf("%d %d", &n, &m);
for(int i=0; i<n; ++i){
adj[i].clear();
visited[i] = false;
}
while(m--){
int u, v;
double w;
scanf("%d %d %lf", &u, &v, &w);
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
double cost[10001]={};
priority_queue<edge> pq;
pq.push({0, 1});
cost[0] = 1;
visited[0] = true;
while(!pq.empty()){
int cur = pq.top().next;
double curW = pq.top().weight;
pq.pop();
if(cur == n-1) break;
for(int i=0; i<adj[cur].size(); ++i){
int next = adj[cur][i].next;
double nextW = cost[cur] * adj[cur][i].weight;
if(!visited[next] || cost[next] > nextW){
visited[next] = true;
cost[next] = nextW;
pq.push({next, nextW});
}
}
}
printf("%lf\n", cost[n-1]);
}
return 0;
}
댓글 없음:
댓글 쓰기