SYSU每周一赛(13.03.16)1003

给定起点终点的无向图,出发时速度为1,到达时速度也为1,在每个点可以进行速度+1,不变,-1的操作,在每条边都有限速,到达一城市后不能直接走反向边,求最短时间。

SPFA作松弛操作的典型例子,设计状态f[i][j][k]为从k城市以j速度到达城市i时的最短时间,然后开一队列依次向下一个城市做递推即可,最后看任意城市以速度1到终点城市的时间最小值即可。递推初值可设置为f[s][0][0],然后做速度必须>0的限制即可保证以速度1出发。

表示依然不太清楚struct或者class能不能直接用=赋值,重载operator =不会写,保险起见,本程序中写了assign()函数进行赋值。

 


             

// Problem#: 7692
// Submission#: 1966931
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct data{
    int city,vel,back;
}s[1000000];
struct data1{
    int city,d,c,next;
}a[1000];
double f[40][110][40];
int inqueue[40][110][40];
int first[40];
int tot;
void assign(struct data &a,struct data b)
{
    a.city=b.city;
    a.vel=b.vel;
    a.back=b.back;
}
void init()
{
    int i,j,k;
    tot=0;
    for (i=0;i<=30;i++)
        for (j=0;j<=110;j++)
            for (k=0;k<=30;k++)
                f[i][j][k]=10000;
    memset(first,0,sizeof(first));
    memset(a,0,sizeof(a));
    memset(inqueue,0,sizeof(inqueue));
}
void addedge(int x,int y,int d,int c)
{
    tot++;
    a[tot].city=y;
    a[tot].d=d;
    a[tot].c=c;
    a[tot].next=first[x];
    first[x]=tot;
    tot++;
    a[tot].city=x;
    a[tot].d=d;
    a[tot].c=c;
    a[tot].next=first[y];
    first[y]=tot;
}
void spfa(int s1,int g)
{
    struct data now,next;
    f[s1][0][0]=0;
    inqueue[s1][0][0]=1;
    now.city=s1;
    now.vel=0;
    now.back=0;
    int head=0,tail=0;
    assign(s[0],now);
    inqueue[s1][0][0]=1;
    while (head<=tail)
    {
        assign(now,s[head]);
        for (int i=first[now.city];i;i=a[i].next)
        {
            if (a[i].city!=now.back)
            for (int j=-1;j<=1;j++)
            if (now.vel+j>0 && now.vel+j<=a[i].c && f[a[i].city][now.vel+j][now.city]>f[now.city][now.vel][now.back]+(double)a[i].d/(now.vel+j))
            {
                f[a[i].city][now.vel+j][now.city]=f[now.city][now.vel][now.back]+(double)a[i].d/(now.vel+j);
                if (!inqueue[a[i].city][now.vel+j][now.city])
                {
                    inqueue[a[i].city][now.vel+j][now.city]=1;
                    next.city=a[i].city;
                    next.vel=now.vel+j;
                    next.back=now.city;
                    tail++;
                    assign(s[tail],next);
                }
            }
        }
        inqueue[now.city][now.vel][now.back]=0;
        head++;
    }
}
int main()
{
    int n,m,s,g,i,j,x,y,d,c;
    while (scanf("%d %d",&n,&m),n|m)
    {
        init();
        scanf("%d %d",&s,&g);
        for (i=1;i<=m;i++)
        {
            scanf("%d %d %d %d",&x,&y,&d,&c);
            addedge(x,y,d,c);
        }
        spfa(s,g);
        double maxtime=10000;
            for (j=0;j<=30;j++)
                if (f[g][1][j]<maxtime)
                    maxtime=f[g][1][j];
        if (s==g)
        {
            printf("0.00000\n");
            continue;
        }
        if (maxtime==10000)
            printf("unreachable\n");
        else
            printf("%.5lf\n",maxtime);
    }
    return 0;
}    

 

posted @ 2013-03-18 17:34  ustc-acm  阅读(191)  评论(0编辑  收藏  举报