[10.4模拟赛]T2
Posted agakiss
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[10.4模拟赛]T2相关的知识,希望对你有一定的参考价值。
T2
Description
现有一个\(n\)个点,\(m\)条无向边的图。要求求出从编号为\(1\)的点到编号为\(n\)的点经过的边的边权的绝对值之和最小的路径。特别的,每经过一条边,图上所有边的边权就会改变,若原边权为x,新的边权是\(\frac11-x\)。
答案保留3位小数
Input
第一行两个整数\(m\),\(n\),表示点数和边数。
接下来\(m\)行,每行三个整数\(u\),\(v\),\(x\),表示有一条连接\(u\),\(v\),边权位\(x\)。
Output
若\(1\)和\(n\)联通,输出最小的边权的绝对值之和
否则输出"chu ti ren shi zhi zhang"(没有引号)。
Sample Input
Sample Output
Data Constraint
对于\(30\)%的数据,\(n<=500\),
Solution
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
#define eps 0.00001
#define MAXN 5000100
struct rec
int nxt, ver;
double dis;
t[MAXN];
struct Rec
int k;
double w;
;
bool operator < (const Rec &x, const Rec &y)
return x.w > y.w;
int n, m, u, v, x, cnt;
int head[MAXN];
bool flag[MAXN];
Rec s;
priority_queue <Rec> h;
inline int read()
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
inline void add(int u, int v, double w)
t[++cnt].nxt = head[u], t[cnt].ver = v, t[cnt].dis = w, head[u] = cnt;
int main()
freopen("pb.in", "r", stdin);
freopen("pb.out", "w", stdout);
n = read(), m = read();
for (register int i = 1; i <= m; i++)
u = read(), v = read(), x = read();
double w = x;
add(u, v + n, fabs(w)), add(v, u + n, fabs(w));
add(u + n, v + 2 * n, fabs(1 / (1 - w))), add(v + n, u + 2 * n, fabs(1 / (1 - w)));
add(u + 2 * n, v, fabs(1 - 1 / w)), add(v + 2 * n, u, fabs(1 - 1 / w));
h.push((Rec)1, 0);
while (!h.empty())
s = h.top();
h.pop();
if (flag[s.k]) continue;
flag[s.k] = true;
if (s.k == n || s.k == 2 * n || s.k == 3 * n) break;
for (register int i = head[s.k]; i; i = t[i].nxt)
int v = t[i].ver;
if (!flag[v])
h.push((Rec)v, s.w + t[i].dis);
if (s.w <= eps) printf("chu ti ren shi zhi zhang");
else printf("%.3f", s.w);
return 0;
以上是关于[10.4模拟赛]T2的主要内容,如果未能解决你的问题,请参考以下文章