1

Тема: Задача

Помогите плз . Вроде задача легкая , но немогу найти ошибку в коде.

http://algoprog.kz/ej/contests/5/statements/svetofori

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
#define f first
#define s second
#define mp make_pair
int n,m,st,fn;
double k,d[100000],xx[100000],yy[100000];
bool u[100000];
vector<pair<int,double> > a[100000]; 

double Calc(double T,int v)
{
                         
    if (v == fn) return T;
    double W = xx[v] + yy[v];
    long long x = (long long)floor(T/W);
    while (x*W < T) x++;

    x--;

    if (x*W + xx[v] >= T) return T;
    
    return x*W + W;
}

int main()
{
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    
    scanf("%d%d%lf",&n,&m,&k);
    for (int i = 0; i < m; i++) {                                     
        int l,r;
        double w;
        scanf("%d%d%lf",&l,&r,&w);
        a[l].push_back(mp(r,w));
        a[r].push_back(mp(l,w));
    }

    for (int i = 1; i <= n; i++) scanf("%lf%lf",&xx[i],&yy[i]);

    scanf("%d%d",&st,&fn);
    
    double inf = (1ll<<59);
    for (int i = 1; i <= n; i++) d[i] = inf;
    d[st] = 0;
    
    while (true) {
        int pos = -1;
        for (int i = 1; i <= n; i++)
        if (!u[i] && (pos == -1 || d[pos] > d[i])) pos = i;

        if (pos == -1 || d[pos] == inf) break;

        u[pos] = true;

        for (int i = 0; i < a[pos].size(); i++) {
            int to = a[pos][i].f;
            double w = a[pos][i].s;

            d[to] = min(d[to],Calc(d[pos]+w*k,to));
        }
    }

    if (d[fn] == inf) puts("-1"); else
    printf("%.4lf",d[fn]);
    return 0;
}

Re: Задача

ooo interesnaya zada4a. i kak mojno rewit ?

3

Re: Задача

Прочитал бегло, на вид - одно из классических применений Дейкстры. Стартуем в стартовой точке A с расстоянием D[A]=0, и потом в Дейкстре если текущая вершина - v со своим D[v], то когда мы просматриваем рёбра-дороги из вершины v, мы каждый раз по формуле находим ближайшее к D[v] время, когда вдоль этой дороги будет гореть зелёный свет, и производим релаксацию.

Таким образом, это некая комбинация жадного алгоритма с Дейкстрой, и понять, почему она верная, не очень сложно.

4

Re: Задача

Ну , я так же решил . Но не выходит sad

5

Re: Задача

Идейно код выглядит правильно. Попробуй только добавить +/- eps в местах где ты сравниваешь double типы.

6

Re: Задача

big_smile Ура ошибку нашел.

d[to] = min(d[to],Calc(d[pos]+w*k,to));
здесь должно быть
d[to] = min(d[to],Calc(d[pos]+w/k,to));

7

Re: Задача

big_smile Ура ошибку нашел.

d[to] = min(d[to],Calc(d[pos]+w*k,to));
здесь должно быть
d[to] = min(d[to],Calc(d[pos]+w/k,to));