生活随笔
收集整理的這篇文章主要介紹了
SYSU每周一赛(13.03.16)1003
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
給定起點終點的無向圖,出發(fā)時速度為1,到達時速度也為1,在每個點可以進行速度+1,不變,-1的操作,在每條邊都有限速,到達一城市后不能直接走反向邊,求最短時間。
SPFA作松弛操作的典型例子,設(shè)計狀態(tài)f[i][j][k]為從k城市以j速度到達城市i時的最短時間,然后開一隊列依次向下一個城市做遞推即可,最后看任意城市以速度1到終點城市的時間最小值即可。遞推初值可設(shè)置為f[s][0][0],然后做速度必須>0的限制即可保證以速度1出發(fā)。
表示依然不太清楚struct或者class能不能直接用=賦值,重載operator =不會寫,保險起見,本程序中寫了assign()函數(shù)進行賦值。
?
?????????????
// 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");elseprintf("%.5lf\n",maxtime);}return 0;
}
?
轉(zhuǎn)載于:https://www.cnblogs.com/USTC-ACM/archive/2013/03/18/2966463.html
總結(jié)
以上是生活随笔為你收集整理的SYSU每周一赛(13.03.16)1003的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。