poj 3621 二分+spfa判负环
来源:互联网 发布:java socket断点下载 编辑:程序博客网 时间:2024/05/01 12:34
http://poj.org/problem?id=3621
求一个环的{点权和}除以{边权和},使得那个环在所有环中{点权和}除以{边权和}最大。
0/1整数划分问题
令在一个环里,点权为v[i],对应的边权为e[i],
即要求:∑(i=1,n)v[i]/∑(i=1,n)e[i]最大的环(n为环的点数),
设题目答案为ans,
即对于所有的环都有 ∑(i=1,n)(v[i])/∑(i=1,n)(e[i])<=ans
变形得ans* ∑(i=1,n)(e[i])>=∑(i=1,n)(v[i])
再得 ∑(i=1,n)(ans*e[i]-v[i]) >=0
稍分析一下,就有:
当k<ans时,就存在至少一个环∑(i=1,n)(k*e[i]-v[i])<0,即有负权回路(边权为k*e[i]-v[i]);
当k>=ans时,就对于所有的环∑(i=1,n)(k*e[i]-v[i])>=0,即没有负权回路。
然后我们就可以使新的边权为k*e[i]-v[i],用spfa来判断负权回路,二分ans。
#include <iostream>#include <cstdlib>#include <cstdio>#include <queue>#include <cstring>#include <algorithm>#define RD(x) scanf("%d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define clr0(x) memset(x,0,sizeof(x))#define clr1(x) memset(x,-1,sizeof(x))using namespace std;typedef long long LL;const int maxn = 1005,maxm = 105;const double eps = 1e-3;const int inf = 0x7fffffff;int v[maxn];struct edge{ int v,w,next; edge(){}; edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};}e[maxn*5];int head[maxn],vis[maxn],_v[maxn],cnt[maxn],ecnt,n,m;double dist[maxn];void add(int u,int v,int w){ e[ecnt] = edge(v,w,head[u]); head[u] = ecnt++;}void init(){ for(int i = 1;i <= n;++i) RD(_v[i]); ecnt = 0; clr1(head);//判负环的初始化 int u,v,w; while(m--){ RD3(u,v,w); add(u,v,w); } return ;}bool spfa(double mid){ clr0(vis),clr0(cnt); fill(dist,dist + n + 1,inf); dist[1] = 0; queue<int> q; q.push(1); while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = false; cnt[u]++; if(cnt[u] > n) return true; for(int i = head[u];i != -1;i = e[i].next){ int v = e[i].v; double tmp = mid*e[i].w - _v[v];//"边权" if(dist[u] + tmp < dist[v]){ dist[v] = dist[u] + tmp; if(!vis[v]){ vis[v] = true; q.push(v); } } } } return false;}void work(){ double l = 0,r = 10000,mid,ans; while(r - l > eps){ mid = (l + r)/2; if(spfa(mid)){ ans = mid; l = mid - 0.000001; }else r = mid + 0.000001; } printf("%.2f\n",ans);}int main(){ while(~RD2(n,m)){ init(); work(); } return 0;}
0 0
- poj 3621 二分+spfa判负环
- poj 3621 二分+spfa
- POJ 3621 (最优比率环 二分+SPFA)
- POJ 3662(二分+SPFA)
- POJ 3621 Sightseeing Cows(01分数规划+二分+Spfa判负环)
- poj 3621(参数搜索+二分+spfa负环求解)
- POJ--2924[Word Rings] (二分+SPFA判正环)
- Poj 3662 Telephone Lines【二分+SPFA】
- POJ-3621-01分数规划,spfa判负环
- POJ 3621 SPFA
- 二分+SPFA
- poj 2112 Optimal Milking(spfa+二分+最大流)
- POJ 3662 Telephone Lines (SPFA、二分搜索)
- [POJ 3662] Telephone Lines (二分答案+SPFA)
- POJ 3662 Telephone Lines 电话线(二分答案+SPFA)
- 【POJ 3259】Wormholes 【spfa判负环】
- poj 3259--Wormholes 【spfa判负环】
- POJ 3259-Wormholes-SPFA判负环
- 设计模式(十四)之Observer
- 一个成功敏捷团队的失败历程
- AES,RSA,ECC加密算法实现
- QT简单获取当期系统时间
- 【jQuery】jQuery自定义插件开发
- poj 3621 二分+spfa判负环
- 【jQuery】jQuery自定义插件开发 —— 示例
- BS和CS的区别以及优缺点
- 26_混合调用服务的案例
- for sdk logo
- 黑马_blog4_集合框架
- 深入理解JavaScript内部原理(1): 执行上下文
- java基础之-IO流(上)
- [LeetCode] Reverse Nodes in K-Group