輝夜's profileKaguya Houraisan's glori...PhotosBlogListsMore ![]() | Help |
|
June, 2008 USACO 3.2.6 Sweet Butter 题解 (续)上一篇在这里。
虽然SPFA已经得出了比较满意的结果,但现在又发现了优化算法,这样一来SPFA就把Dijkstra甩开了一大截。
下面直接引用我在上一篇的留言:
对于APSP问题如果用单源最短路径算法的话,曾考虑过用先求出的最短路径优化,使得在后面求新源点的最短路径时对已求过的点之间可以一次优化到最终结果避免多次进入队列更新,这个优化对SPFA算法尤其明显。不过这样一来就需要用邻接矩阵储存边,对稀疏图来说需要空间比较多,也可以看成是一种DP的思想吧(空间换时间)。虽然最短路存在了邻接矩阵中,但对稀疏图计算时还是用邻接表算,这个效率依然是最高的(实践验证过,用时相差10倍以上)。
今天实践了一下,发现具体实现和开始想的优化方法还有些不同:只能在求过的点中取一点进行优化(多了效果不升反降)
#include<fstream> #include<vector> #include<list> #include<queue> using namespace std; const int infinite=1000000000;
int nCow,nPasture,nConnect; vector<int> vCowsAt; vector< list< pair<int,int> > > vPasAjt; vector< vector<int> > vDistMatrix; inline bool relax(int u, int v, int weight, vector<int> &d){
int newlength=d[u]+weight; if(newlength<d[v]){ d[v]=newlength; return true; } return false; } int CalPathSum(int iSource){
queue<int> Q; vector<bool> IsInQ(nPasture); // optimizing begin:
if(iSource>0){ int iShort=0; for(int k=1;k<iSource;++k)if(vDistMatrix[k][iSource]<vDistMatrix[iShort][iSource]) iShort=k; for(int iDes=0;iDes<nPasture;++iDes) vDistMatrix[iSource][iDes]=vDistMatrix[iShort][iSource]+vDistMatrix[iShort][iDes]; } // optimizing end. vDistMatrix[iSource][iSource]=0;
Q.push(iSource); IsInQ[iSource]=true; while(!Q.empty()){
int u=Q.front(); Q.pop(); IsInQ[u]=false; for(list< pair<int,int> >::iterator itr=vPasAjt[u].begin();itr!=vPasAjt[u].end();++itr){ int v=itr->first; if(relax(u,v,itr->second,vDistMatrix[iSource]) && !IsInQ[v]){ Q.push(v); IsInQ[v]=true; } } } int sum=0;
for(int i=0;i<nCow;++i)sum+=vDistMatrix[iSource][vCowsAt[i]]; return sum; } int main(){
ifstream fin("butter.in"); ofstream fout("butter.out"); fin>>nCow>>nPasture>>nConnect; vCowsAt.resize(nCow); vPasAjt.resize(nPasture); vDistMatrix.resize(nPasture); for(int i=0;i<nPasture;++i) vDistMatrix[i].resize(nPasture,infinite); for(int i=0;i<nCow;++i){
int iPasture; fin>>iPasture; vCowsAt[i]=iPasture-1; } for(int i=0;i<nConnect;++i){ int u,v,distance; fin>>u>>v>>distance; vPasAjt[u-1].push_back(pair<int,int>(v-1,distance)); vPasAjt[v-1].push_back(pair<int,int>(u-1,distance)); } int minpath=infinite;
for(int i=0;i<nPasture;++i) minpath=min(minpath,CalPathSum(i)); fout<<minpath<<endl;
} 程序变化不大,只是多了对 vDistMatrix 矩阵的处理,并加上了优化部分(已标出)。由于使用了动态空间分配,内存占用没有想象的增加那么多。
下面是运行结果:
TASK: butter LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.022 secs, 2852 KB]
Test 2: TEST OK [0.000 secs, 2856 KB]
Test 3: TEST OK [0.000 secs, 2856 KB]
Test 4: TEST OK [0.000 secs, 2852 KB]
Test 5: TEST OK [0.011 secs, 2856 KB]
Test 6: TEST OK [0.011 secs, 2988 KB]
Test 7: TEST OK [0.043 secs, 3512 KB]
Test 8: TEST OK [0.065 secs, 4308 KB]
Test 9: TEST OK [0.086 secs, 5364 KB]
Test 10: TEST OK [0.108 secs, 5360 KB]
All tests OK.
时间几乎缩短了一半,可惜最后一个测试点差点突破 0.1secs ... Comments (4)
TrackbacksThe trackback URL for this entry is: http://dantvt.spaces.live.com/blog/cns!D87988A6CAC0A480!775.trak Weblogs that reference this entry
|
|
|