【bzoj 1486】 [HNOI2009]最小圈

来源:互联网 发布:智能导游app 知乎 编辑:程序博客网 时间:2024/05/21 19:31

1486: [HNOI2009]最小圈

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 2272  Solved: 1065
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

4 5
1 2 5
2 3 5
3 1 5
2 4 3
4 1 3

Sample Output

3.66666667
二分加spfa判负环,如按照bfs式的spfa 复杂度会达到O(n*m) 就T了,就需要改成dfs式的spfa,在判断时只要判断是否在栈中存在这个节点,如果有,而且还需要更新这个节点的值,那么就是有负环了。具体见代码。
没注意到是单向边,和莫名把b数组开成int
#include<bits/stdc++.h>using namespace std;#define eps 1e-9#define debug(x) cout<<#x<<" = "<<x<<endl;const int maxn = 3050 , maxm = 10050;int n,m,len,h[maxn],nx[maxm<<1],to[maxm<<1],u[maxm],v[maxm];double co[maxm<<1],cost[maxm];bool vis[maxn],ready;double d[maxn];void add_edge(int a,int b,double c){to[++len]=b;nx[len]=h[a];h[a]=len;co[len]=c;}void mfy(double dv){memset(h,0,sizeof(h));len=0;for(int i=1;i<=m;i++){add_edge(u[i],v[i],cost[i]-dv);}}void dfs(int nd){vis[nd]=1;for(int i=h[nd];i;i=nx[i]){if(d[to[i]] > d[nd] + co[i]){if(vis[to[i]]){ready=1;return;}d[to[i]] = d[nd] + co[i];dfs(to[i]);if(ready)return ;}}vis[nd]=0;}bool spfa(){ready=0;memset(d,0,sizeof(d));memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++){dfs(i);if(ready)return 1;}return 0;}int main(){int ba,bb;double bc;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d %d %lf",&ba,&bb,&bc);u[i]=ba;v[i]=bb;cost[i]=bc;}double l=-1e7,r=1e7,mid,ans;while(r-l > eps){mid =(l+r)/2.0;mfy(mid);spfa();if(!ready){l=mid;}else{ans=mid;r=mid;}}printf("%.8f",ans);return 0;}






1 0
原创粉丝点击