poj1860(spfa)
来源:互联网 发布:淘宝大学vip靠谱吗 编辑:程序博客网 时间:2024/05/20 03:42
两种情况YES,一种是存在正权回路;
一种是求最长路后,实现了增值,也是YES;
用spfa来判断是否存在正权回路,其实spfa是可以用来判断是否存在回路的,不管是正权还是负权,只不过它们松弛的条件不同,正权的话,我们是往dis[]权值增大的方向松弛,负权的话,我们是往dis[]权值减少的方向松弛,然后判断是否存在回路只要看有没有一点入队列的次数大于n就行了用spfa来判断是否存在正权回路,其实spfa是可以用来判断是否存在回路的,不管是正权还是负权,只不过它们松弛的条件不同,正权的话,我们是往dis[]权值增大的
如果存在一个环(从某个点出发又回到自己的路径),而且这个环上所有权值之和是负数,那这就是一个负权环,也叫负权回路;同理正权回路;
#include <iostream>#include <cstdio>#include <cstring>#include <stdlib.h>#include <math.h>#include <queue>#include <algorithm>using namespace std;#define N 210#define INF 0xfffffffdouble dist[N], V;int cnt, Head[N], num[N], vis[N];int n, m, s;struct Edge{ int v, next; double r, c;}e[N];void Add(int u, int v, double r, double c){ e[cnt].v = v; e[cnt].r = r; e[cnt].c = c; e[cnt].next = Head[u]; Head[u] = cnt++;}//spfa模板/*int spfa(int src,int n){//用队列实现int i;memset(cnt,0,sizeof(cnt));//入队次数memset(vis,false,sizeof(vis));//for(i=1;i<=n;i++)dist[i]=INF;dist[src]=0;queue<int>Q;Q.push(src);vis[src]=true;++cnt[src];while(!Q.empty()){ int u,v; u=Q.front();Q.pop();vis[u]=false; for(i=head[u];i!=-1;i=nxt[i]){ v=pnt[i]; if(1==relax(u,v,cost[i])&&!vis[v]){ Q.push(v);vis[v]=true; if((++cnt[v])>n)return -1;//cnt[i]为入队列次数,用来判断是否存在负权回路 } }}if(dist[n]==INF)return -2;//src和n不可达,有些题目可省return dist[n];//返回src到n的最短距离,根据题意不同而改变}*/bool spfa()///spfa模板;{ memset(vis, 0, sizeof(vis)); memset(num, 0, sizeof(num)); queue<int>Q; vis[s] = 1; dist[s] = V; Q.push(s); num[s]++; while(Q.size()) { int p=Q.front(); Q.pop(); vis[p] = 0; for(int i=Head[p]; i!=-1; i=e[i].next) { int q = e[i].v; if(dist[q] < (dist[p] - e[i].c) * e[i].r)///注意松弛的变化; { dist[q] = (dist[p] - e[i].c) * e[i].r; if(!vis[q]) { vis[q] = 1; Q.push(q); num[q] ++; if(num[q]>n) return true;///存在正权回路; } } } } if(dist[s]>V)///最长路后,实现了增值; return true; return false;}int main(){ int a, b; double rab, rba, cab, cba; while(scanf("%d%d%d%lf", &n, &m, &s, &V)!=EOF) { cnt = 0; memset(Head, -1, sizeof(Head)); memset(dist, 0, sizeof(dist)); for(int i=1; i<=m; i++) { scanf("%d%d%lf%lf%lf%lf", &a, &b, &rab, &cab, &rba, &cba); Add(a, b, rab, cab); Add(b, a, rba, cba); } if( spfa() ) printf("YES\n"); else printf("NO\n"); } return 0;}
0 0
- poj1860(spfa)
- spfa && poj1860
- poj1860 spfa
- POJ1860 SPFA
- poj1860 Currency Exchange(spfa)
- poj1860(spfa)
- 【POJ1860】Currency Exchange【spfa判正环】
- poj1860 spfa判断负环
- POJ1860 SPFA判断正环
- poj1860 Currency Exchange(bellman+spfa解法)
- poj1860 货币转换 spfa+Bellman-Ford
- poj1860
- poj1860
- poj1860
- poj1860
- poj1860
- poj1860
- poj1860
- git命令图解
- c-c++:extern的些许感悟
- 转 C++11与Unicode及使用标准库进行UTF-8、UTF-16、UCS2、UCS4/UTF-32编码转换 utf8转utf16 utf16转utf8
- 单词2016.8.3
- 源码管理工具SVN:Eclipse下的使用
- poj1860(spfa)
- html,js,css轮播插件
- POJ1644 DP+一些感悟
- raphaelJs的简单使用
- 置顶操作的实现
- 从应用到平台,云服务架构的演进过程
- 关于安卓边下边播的几点心得
- 1007. 素数对猜想 (20)
- Java并发编程:并发容器之CopyOnWriteArrayList(转载)