bzoj 1486: [HNOI2009]最小圈

二分答案+dfs判有没有负环,这样dfs比spfa快多了。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<vector>
 9 #define M 2000009
10 #define EPS 1e-10
11 #define ll long long
12 using namespace std;
13 ll read()
14 {
15     char ch=getchar();
16     ll x=0,f=1;
17     for(;ch<'0'||ch>'9';ch=getchar())
18         if(ch=='-')
19           f=-1;
20     for(;ch>='0'&&ch<='9';ch=getchar())
21         x=x*10+ch-'0';
22     return x*f;
23 }
24 int cnt,n,m,head[M],next[M],u[M];
25 double ans,v[M],l=0x7fffffff,r=-0x7fffffff,d[M];
26 bool f[M];
27 void jia(int a1,int a2,double a3)
28 {
29     cnt++; 
30     next[cnt]=head[a1];
31     head[a1]=cnt;
32     u[cnt]=a2;
33     v[cnt]=a3;
34 }
35 bool dfs(int x)
36 {
37   f[x]=1;
38   for(int i=head[x];i;i=next[i])
39     if(d[u[i]]>d[x]+v[i])
40       {
41         if(f[u[i]])
42           return 1;
43         d[u[i]]=d[x]+v[i];
44         if(dfs(u[i]))
45           return 1;
46       }
47   f[x]=0;
48   return 0;
49 }
50 bool pa()
51 {
52   for(int i=1;i<=n;i++)
53     if(dfs(i))
54       return 1;
55   return 0;
56 }
57 bool pan(double x)
58 {
59   memset(d,0,sizeof(d));
60   memset(f,0,sizeof(f));
61   for(int i=1;i<=n;i++)
62     for(int j=head[i];j;j=next[j])
63       v[j]-=x;
64   bool an=pa();
65   for(int i=1;i<=n;i++)
66     for(int j=head[i];j;j=next[j])
67       v[j]+=x;
68   return an; 
69 }
70 int main()
71 {
72    n=read();
73    m=read();
74    for(int i=1;i<=m;i++)
75      {
76        int a1=read(),a2=read();
77        double a3;
78        scanf("%lf",&a3);
79        jia(a1,a2,a3);
80        l=min(l,a3);
81        r=max(r,a3);
82      }
83    for(;r-l>1e-9;)
84      {
85        double mid=(l+r)/2;
86        if(pan(mid))
87          {
88            r=mid;
89            ans=mid;
90          }
91        else
92          l=mid;
93      }
94    printf("%.8lf\n",ans);
95    return 0;
96 }

 

posted @ 2016-07-07 07:55  xiw5  阅读(114)  评论(0编辑  收藏  举报