【分数规划总结】周测图论1 环 & CODEVS 1183 泥泞的道路
来源:互联网 发布:如何做一名网络写手 编辑:程序博客网 时间:2024/05/18 02:34
(s1+s2+…+sn)/(t1+t2+…+tn) = ans
即s1-t1*ans+s2-t2*ans+…+sn-tn*ans = 0
当需求比值解时考虑分数规划,二分答案求解。根据题目要求向上二分或向下二分,利用spfa判正/负环。
环
定义环的伸展度为这个环上所有边的距离之和与环上边的总数的比值,给出一个n个节点,m条边的有向图,每条边有一个属性距离,求图中伸展度最小的有向环。
输入说明:
第一行2个正整数n、m。
接下来m行每行3个正整数u,v,d,表示一条由u到v距离为d的单向道路。
输出说明:四舍五入,输出1个7位小数表示最小的伸展度。
样例输入:
2 2
1 2 1
2 1 2
样例输出:
1.5000000
数据说明:
对于20%的数据,n<=100,m<=1000
对于40%的数据,n<=1000,m<=-5000
对于100%的数据,n<=3000,m<=10000
数据保证至少有一个环
//二分+dfs版spfa判负环,因为是判负环所以d初值为0,dfs时要循环所有的点,防止漏。//负环条件是dfs是搜到的点仍在队列中。 #include<cstdio>#include<algorithm>#include<cstring>#include<iostream>using namespace std;const double eps = 1e-9;const int inf = 0x3f3f3f3f;const int maxn = 3030;const int maxm = 10010;int n, m, tot, f;int st[maxn], in[maxn];double d[maxn];struct node{ int to, w, next; double wt;} edge[maxm];void ini(int u, int v, int d){ edge[++tot].to = v; edge[tot].w = d; edge[tot].next = st[u]; st[u] = tot;}void spfa(int rt){ in[rt] = 1; for(int i = st[rt]; i > 0; i = edge[i].next){ int v = edge[i].to; if(d[v] > d[rt] + edge[i].wt){//存在负值才更新距离。 if(in[v]){//再次到v比原来松弛过的距离还短,说明有负环。 f = 1; return; } else{ d[v] = d[rt] + edge[i].wt; spfa(v); } } } in[rt] = 0;}bool check(double x){ memset(in, 0, sizeof(in)); memset(d, 0, sizeof(d)); for(int i = 1; i <= tot; i++) edge[i].wt = (double)edge[i].w - x; f = 0; for(int i = 1; i <= n; i++){ spfa(i); if(f) return f; } return f;}int main(){ cin >> n >> m; for(int i = 1, u, v, d; i <= m; i++){ cin >> u >> v >> d; ini(u, v, d); } double l = 0, r = 10000000, mid; while(r - l > eps){ mid = (l+r) / 2; if(check(mid)) r = mid; else l = mid; } printf("%.7lf\n", r); return 0;}
CODEVS 1183 泥泞的道路
//二分答案BFS找正环。 #include<cstdio>#include<queue>#include<algorithm>#include<cstring>#include<iostream>using namespace std;const double eps = 1e-4;const int inf = 0x3f3f3f3f;const int maxn = 210;int n, p[maxn][maxn], t[maxn][maxn], in[maxn], hash[maxn];double f[maxn][maxn];double d[maxn];bool spfa(){ queue<int> q; d[1] = 0; in[1] = 1; q.push(1); while(!q.empty()){ int u = q.front(); q.pop(); in[u] = 0; for(int i = 1; i <= n; i++){ if(p[u][i] && d[i] < d[u] + f[u][i]){ d[i] = d[u] + f[u][i]; if(!in[i]){ in[i] = 1; q.push(i); hash[i]++; if(hash[i] >= n) return true;//BFS版SPFA的判环条件,入队 >= n次。 } } } } if(d[n] > 0) return true;//注意要添这一步,更新到n大于0,说明可以更优。 return false;}bool check(double x){ memset(f, 0, sizeof(f)); memset(in, 0, sizeof(in)); memset(hash, 0, sizeof(hash)); for(int i = 0; i <= n; i++) d[i] = -inf; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) f[i][j] = (double)p[i][j] - t[i][j] * x; if(spfa()) return true; else return false;}int main(){ cin >> n; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) cin >> p[i][j]; for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) cin >> t[i][j]; double l = 0, r = 100000, mid; while(r - l > eps){ mid = (l+r) / 2; if(check(mid)) l = mid; else r = mid; } printf("%.3lf\n", l); return 0;}
阅读全文
0 0
- 【分数规划总结】周测图论1 环 & CODEVS 1183 泥泞的道路
- CODEVS 1183 泥泞的道路 二分+01分数规划(双倍经验)
- codevs 1183 泥泞的道路
- Codevs 1183 泥泞的道路
- Codevs 1183 泥泞的道路
- 【codevs 1183】泥泞的道路
- Codevs 1183 泥泞的道路
- 【CODEVS 1183】泥泞的道路 SPFA+二分
- codevs 1183 泥泞的道路 二分+SPFA最长路
- codevs 1183 泥泞的道路(spfa+二分答案)
- codevs 1183 泥泞的道路(二分答案+spfa验证)
- codevs 1183 泥泞的道路 (spfa +二分)
- <二分答案+spfa验证>codevs 1183 泥泞的道路
- codevs 1183 泥泞的道路 最长路 解题报告
- codevs 1183 泥泞的道路 图论,spfa判环,二分答案
- codevs1183 泥泞的道路
- Codevs1183 泥泞的道路
- 泥泞的道路
- IEEE 2017视频
- Hibernate_day01
- [poj 3321]:Apple Tree(树状数组/线段树 和dfs序)
- 比较取得两个字符串数组中相同元素和不同元素
- 安装VMware及新建虚拟机
- 【分数规划总结】周测图论1 环 & CODEVS 1183 泥泞的道路
- 【C# / 算法】输出任意阶回旋矩阵
- android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
- 汇编语言: 逆序输出字符串“BASED ADDRESSING”
- android monkey真机测试
- 源代码安全解决方案,信息安全网络安全
- opencv之图像拼接
- Android 使用LeakCanary 检测内存泄露
- vc6 移植到vs2013