UVA 11090 Going in Cycle!!
2015-09-09 21:42
405 查看
思路:
具体题解大白书上写的很清楚。属于0/1分数规划类型的题,做法类似。重要是体会这种转化的过程和思路,二分枚举最小的平均值,然后经过式子变形后转化为判断新建边权的图中是否存在负环,思路好巧妙啊!SPFA一个最重要的应用就是判负环,而这样的应用又可以间接用来解决其它问题!
代码君:
具体题解大白书上写的很清楚。属于0/1分数规划类型的题,做法类似。重要是体会这种转化的过程和思路,二分枚举最小的平均值,然后经过式子变形后转化为判断新建边权的图中是否存在负环,思路好巧妙啊!SPFA一个最重要的应用就是判负环,而这样的应用又可以间接用来解决其它问题!
代码君:
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <iostream> #include <cmath> #include <map> #include <vector> #include <set> #include <string> #define PB push_back #define FT first #define SD second #define MP make_pair #define INF 0x3f3f3f3f using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> P; const int maxn=5+1e5,MOD=7+1e9; struct Edge { int from,to; double dis; Edge(int _from, int _to, double _dis) {from=_from,to=_to,dis=_dis;} }; struct BellmanFord { int n,m; vector<Edge> edges; vector<int> G[maxn]; bool inq[maxn]; double d[maxn]; int p[maxn]; int cnt[maxn]; void init(int n) { this->n = n; for(int i = 0;i < n;i ++){ G[i].clear(); } edges.clear(); } void addedge(int u,int v,double dis) { edges.PB((Edge){u, v, dis}); m = edges.size(); G[u].PB(m - 1); } bool negativeCycle() { queue<int> Q; memset(cnt, 0, sizeof(cnt)); for(int i = 0;i < n;i ++){ d[i] = 0.0; inq[i] = 1; Q.push(i); } while(!Q.empty()){ int u = Q.front(); Q.pop(); inq[u] = 0; for(int i = 0;i < G[u].size();i ++){ Edge& e=edges[G[u][i]]; if(d[e.to] > d[u] + e.dis) { d[e.to] = d[u] + e.dis; p[e.to] = G[u][i]; if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; if(++ cnt[e.to] > n) return 1; } } } } return 0; } }solver; bool test(double x) { for(int i = 0;i < solver.m;i ++){ solver.edges[i].dis -= x; } bool res = solver.negativeCycle(); for(int i = 0;i < solver.m;i ++){ solver.edges[i].dis += x; } return res; } int main() { int n, m, T, ca=0; scanf("%d",&T); while(T -- ){ scanf("%d%d",&n,&m); solver.init(n); double _max = 0; for(int i = 0;i < m;i ++){ int u,v; double w; scanf("%d%d%lf" ,&u,&v,&w); u--, v--; _max = max(_max,w); solver.addedge(u,v,w); } printf("Case #%d: ",++ca); if(!test(_max+1)) printf("No cycle found.\n"); else { double L = 0, R = _max; while(R - L > 1e-3) { double M = L + (R - L)/2; if(test(M)) R = M; else L = M; } printf("%.2lf\n",L); } } //system("pause"); return 0; }
相关文章推荐
- CSU1307 并查集+SPFA
- 单源最短路深度分析
- USACO/butter 3.2.6
- hdu 1596 find the safest road(spfa算法)
- MZ Training 2014 #8 F题
- MZ Training 2014 #4 B题
- [网络流24题 #18]分配问题
- [网络流24题 #18]分配问题
- 收益最大
- acm-hdu2544解题报告
- hdu2112 spfa
- POJ 3037 Skiing SPFA
- POJ 3255 Roadblocks 次短路 SPFA
- poj 1511 Invitation Cards
- poj 1724 ROADS 邻接表+优先队列+spfa()
- hdu 1224 Free DIY Tour
- hdu2544最短路——spfa
- hdu1548A strange lift——最短路(迪杰斯特拉,spfa)。bfs(队列。数组)
- poj 1201 interval 差分约束/贪心+线段树区间更新
- HDU 2544 最短路(四种写法:Floyd、Dijkstra、Bellman-Ford、SPFA)