T1 最小圈 bzoj 1486

题目大意:

一个环的权值平均值为定义为一个这个环上所有边的权值和除以边数

求最小的环的权值平均值

思路:

二分一个值 把所有边减去这个值 

判断是否有负环

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 1061109567
10 #define ll long long
11 #define MAXN 6010
12 #define eps 1e-9
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,m,vis[MAXN],fa[MAXN],q[MAXN],f;
22 double l,r,mid,ans,dis[MAXN],val[MAXN<<1],v[MAXN<<1];
23 int to[MAXN<<1],nxt[MAXN<<1],fst[MAXN],cnt;
24 void add(int u,int v,double w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
25 void spfa(int x)
26 {
27     vis[x]=1;
28     for(int i=fst[x];i;i=nxt[i])
29         if(dis[x]+v[i]<dis[to[i]])
30             if(vis[to[i]]){f=1;return;}
31             else {dis[to[i]]=v[i]+dis[x];spfa(to[i]);}
32     vis[x]=0;
33 }
34 int check(double x)
35 {
36     for(int i=1;i<=cnt;i++) v[i]=val[i]-x;
37     for(int i=1;i<=n;i++) dis[i]=0.0;
38     memset(vis,0,sizeof(vis));f=0;
39     for(int i=1;i<=n;i++)
40         {spfa(i);if(f) return 1;}
41     return 0;
42 }
43 int main()
44 {
45     n=read(),m=read();int a,b;double c;
46     while(m--) {a=read(),b=read();scanf("%lf",&c);add(a,b,c);}
47     l=-1e7,r=1e7;
48     while(r-l>=eps)
49     {
50         mid=(l+r)/2.0;
51         if(check(mid)) ans=mid,r=mid-eps;
52         else l=mid+eps;
53     }
54     printf("%.8lf",ans);
55 }
View Code

相关文章:

  • 2021-10-07
  • 2022-12-23
  • 2022-12-23
  • 2021-05-23
  • 2021-05-22
  • 2021-10-04
  • 2022-12-23
  • 2022-02-23
猜你喜欢
  • 2021-07-14
  • 2022-01-30
  • 2021-11-21
  • 2022-12-23
  • 2021-11-21
  • 2021-08-05
  • 2021-08-29
相关资源
相似解决方案