UVA11090 Going in Cycle (二分+判负环)
2015-09-04 10:37
573 查看
二分法+spfa判负环。如果存在一个环sum(wi)<k*x,i=0,1,2...,k,那么每条边减去x以后会形成负环。因此可用spfa来判负环。
一般spfa判负环dfs最快,用stack次之,queue最慢,因为一个负环中被更新的点是连续的。
一开始不知到图的连通情况,所以把所有点都入栈更新。
dfs+判负环
一般spfa判负环dfs最快,用stack次之,queue最慢,因为一个负环中被更新的点是连续的。
一开始不知到图的连通情况,所以把所有点都入栈更新。
#include<bits/stdc++.h> using namespace std; const int maxn = 51; struct Edge { int v,nxt; double w; }; vector<Edge> edges; int head[maxn]; #define PB push_back void addEdge(int u,int v,double w) { edges.PB({v,head[u],w}); head[u] = edges.size()-1; } bool vis[maxn]; double d[maxn]; int cnt[maxn]; bool spfa(int n) { stack<int>S; memset(vis,0,sizeof(vis)); memset(cnt,0,sizeof(cnt)); for(int i = 0; i < n; i++) { vis[i] = true; d[i] = 0.; S.push(i); } while(S.size()){ int u = S.top(); S.pop(); vis[u] = false; for(int i = head[u]; ~i; i = edges[i].nxt){ Edge &e = edges[i]; if(d[e.v]>d[u]+e.w){ d[e.v] = d[u]+e.w; if(!vis[e.v]){ S.push(e.v); vis[e.v] = true; if(++cnt[e.v] > n) return true; } } } } return false; } bool P(double x,int n) { for(int i = 0; i < (int)edges.size(); i++) edges[i].w -= x; bool ret = spfa(n); for(int i = 0; i < (int)edges.size(); i++) edges[i].w += x; return ret; } void init() { memset(head,-1,sizeof(head)); edges.clear(); } const double eps = 1e-4; int main() { //freopen("in.txt","r",stdin); int T;cin>>T; int kas = 0; while(T--){ init(); int n,m; scanf("%d%d",&n,&m); double l = 0, r = 0; while(m--){ int u,v; double w; scanf("%d%d%lf",&u,&v,&w); addEdge(u-1,v-1,w); r = max(r,w); } printf("Case #%d: ",++kas); if(!P(r+1,n)) { puts("No cycle found."); continue; } for(double mid; r-l>eps; P(mid,n)?r=mid:l=mid) mid = l+(r-l)/2; printf("%.2lf\n",l); } return 0; }
dfs+判负环
bool vis[maxn]; double d[maxn]; bool dfs(int u) { vis[u] = true; for(int i = head[u]; ~i ; i = edges[i].nxt){ Edge &e = edges[i]; if(d[e.v] > d[u]+e.w){ d[e.v] = d[u]+e.w; if(!vis[e.v]){ if(dfs(e.v)) return true; }else return true; } } vis[u] = false; return false; } 调用 for(int u = 0; u < n; u++){ if(dfs(u)) { ret = true; break; } }
相关文章推荐
- Microsoft Natural Ergonomic 4000 zoom改键
- django 1.8 官方文档翻译: 3-3-2 File对象
- GO语言学习笔记3(函数接口并发)
- GO语言学习笔记2(指针数组MAP)
- poj 1179 Polygon
- go (golang) DNS域名解析实现
- 第二章 概述
- POJ 1003 Hangover
- 访问google的一些方法
- mongo 常用的命令
- 谷歌Logo的变迁之路:从课后作业级走向世界级
- 运用Polygon类绘制六边形
- <转>四个重要属性——Action、Data、Category、Extras
- 【英语】Bingo口语笔记(63) - 一个单词的多种发音
- 【英语】Bingo口语笔记(62) - 生气道歉场景的表达
- Goods:图书模块按分类查询各层实现
- 第三方Windows To Go工具Rufus下载:把Win10操作系统装进U盘
- Django的CSRF保护引起的403 FORBIDDEN
- go mode
- 用了17年的Google Logo大改了