Cod sursa(job #602293)

Utilizator mihai995mihai995 mihai995 Data 10 iulie 2011 16:01:56
Problema Drumuri minime Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.97 kb
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;

const int N=15000;
const double E=1e-8,inf=2000000000;
double dist[N];
int v[10*N],nr[N],n;
bool use[N];
struct arc{int y;double c;};
vector<arc> a[N];

ifstream in("dmin.in");
ofstream out("dmin.out");

inline double modul(double a)
{
    return a>0 ? a : -a;
}

inline bool bigger(double a,double b)
{
    return a-b>E;
}

inline bool egal(double a,double b)
{
    return modul(a-b)<E;
}

inline bool cmp(int a,int b)
{
    return bigger(dist[b],dist[a]);
}

inline void sch(int& a,int& b)
{
    int c=a;a=b;b=c;
}

void up(int x)
{
    if (x>1 && cmp(v[x],v[x>>1]))
    {
        sch(v[x],v[x>>1]);
        up(x>>1);
    }
}

void down(int x)
{
    int m=x,S=x<<1,D=S+1;
    if (S<=v[0] && cmp(v[S],v[m]))
        m=S;
    if (D<=v[0] && cmp(v[D],v[m]))
        m=D;
    if (x!=m)
    {
        sch(v[m],v[x]);
        down(m);
    }
}

void push(int x)
{
    v[++v[0]]=x;
    up(v[0]);
}

void pop(int& x)
{
    x=v[1];
    v[1]=v[v[0]--];
    down(1);
}

void dijkstra(int x)
{
    int y;
    double c;
    push(x);
    while (v[0])
    {
        pop(x);
        if (use[x])
            continue;
        use[x]=true;
        for (vector<arc>::iterator i=a[x].begin();i!=a[x].end();i++)
        {
            y=(*i).y;c=(*i).c;
            if (bigger(dist[y],dist[x]+c))
            {
                dist[y]=dist[x]+c;
                push(y);
                nr[y]=0;
            }
            if (egal(dist[y],dist[x]+c))
                nr[y]+=nr[x];
        }
    }
}

int main()
{
    int x,y,c,i,m;
    in>>n>>m;
    while (m--)
    {
        in>>x>>y>>c;
        a[x].push_back((arc){y,log(c)});
        a[y].push_back((arc){x,log(c)});
    }
    for (i=1;i<=n;i++)
        dist[i]=inf;
    nr[1]=1;dist[1]=0;
    dijkstra(1);
    for (i=2;i<=n;i++)
        out<<nr[i]<<" ";
    out<<"\n";
    return 0;
}