首页 > 代码库 > 20140710 loop
20140710 loop
此题说多了都是泪,明明知道SPFA能找负环,却偏偏用了DFS
SPFA调试成功
1 #include<cstdio> 2 #include<vector> 3 #include<queue> 4 #include<memory.h> 5 #define MAXV 600 6 #define INF 0x3f3f3f3f 7 8 using std::vector; 9 using std::queue;10 11 struct Edge{12 double v; 13 int to; 14 };15 16 vector<Edge> e[MAXV]; 17 double dist[MAXV]; 18 int cnt[MAXV]; 19 queue<int> buff; 20 bool done[MAXV]; 21 int V; //节点数22 int E; //边数23 24 bool spfa(double k){ //返回值:TRUE为找到最短路返回,FALSE表示出现负环退出25 memset(cnt,0,sizeof(cnt));26 memset(done,0,sizeof(done));27 for(int i=0;i<V;i++){ //初始化:将除了原点st的距离外的所有点到st的距离均赋上一个极大值28 dist[i]=INF; //非原点距离无穷大29 }30 dist[0]=0;31 buff.push(0); //原点入队32 done[0]=1; //标记原点已经入队33 cnt[0]=1; //修改入队次数为134 while(!buff.empty()){ //队列非空,需要继续松弛35 int tmp=buff.front(); //取出队首元素36 for(int i=0;i<(int)e[tmp].size();i++){ //枚举该边连接的每一条边37 Edge *t=&e[tmp][i]; //由于vector的寻址速度较慢,故在此进行一次优化38 if(dist[tmp]+(*t).v-k<dist[(*t).to]){ //更改后距离更短,进行松弛操作39 dist[(*t).to]=dist[tmp]+(*t).v-k; //更改边权值40 if(!done[(*t).to]){ //没有入队,则将其入队41 buff.push((*t).to); //将节点压入队列42 done[(*t).to]=1; //标记节点已经入队43 cnt[(*t).to]+=1; //节点入队次数自增44 if(cnt[(*t).to]>V){ //已经超过V次,出现负环45 while(!buff.empty())buff.pop(); //清空队列,释放内存46 return false; //返回FALSE47 }48 }49 }50 }51 buff.pop();//弹出队首节点52 done[tmp]=0;//将队首节点标记为未入队53 }54 return true; //返回TRUE55 } //算法结束56 57 int main(){ //主函数58 scanf("%d%d",&V,&E); //读入点数和边数59 for(int i=0,x,y;i<E;i++){60 double l;61 scanf("%d%d%lf",&x,&y,&l); //读入x,y,l表示从x->y有一条有向边长度为l62 x--,y--;63 Edge tmp; //设置一个临时变量,以便存入vector64 tmp.v=l; //设置边权65 tmp.to=y; //设置连接节点66 e[x].push_back(tmp); //将这条边压入x的表中67 }68 double l=0,r=1e+9,mid=(l+r)/2;69 for(int i=1;i<=100;i++) {70 if(spfa(mid)) l=mid;71 else r=mid;72 mid=(l+r)/2;73 }74 printf("%.2lf\n",mid);75 return 0;76 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。