首页 > 代码库 > UVA11090 Going in Cycle!! [spfa负环]

UVA11090 Going in Cycle!! [spfa负环]

https://vjudge.net/problem/UVA-11090

平均权值最小的回路


 

为后面的做个铺垫

二分最小值,每条边权减去他,有负环说明有的回路平均权值小于他

spfa求负环的时候可以先把所有点加到队列里,d[i]=0

 

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int N=55;const double eps=1e-3,INF=1e9;inline int read(){    char c=getchar();int x=0,f=1;    while(c<0||c>9){if(c==-)f=-1;c=getchar();}    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}    return x*f;}int n,m,u,v;double w;struct edge{    int v,ne;    double w;}e[N*N];int h[N],cnt=0;inline void ins(int u,int v,int w){    cnt++;    e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;}double d[N];int q[N],head,tail,inq[N],num[N];inline void lop(int &x){if(x==N) x=1;}bool spfanc(double mid){    for(int i=1;i<=n;i++) d[i]=INF;    head=tail=0;    memset(inq,0,sizeof(inq));    memset(num,0,sizeof(num));    for(int i=1;i<=n;i++) d[i]=0.0,inq[i]=1,q[tail++]=i;    while(head!=tail){        int u=q[head++];inq[u]=0;lop(head);        for(int i=h[u];i;i=e[i].ne){            int v=e[i].v;double w=e[i].w-mid;            if(d[v]>d[u]+w){                d[v]=d[u]+w;                if(!inq[v]){                    inq[v]=1,q[tail++]=v,lop(tail);                    if(++num[v]>n) return true;                }            }        }    }    return false;}int main(){    int T=read(),cas=0;    while(T--){        printf("Case #%d: ",++cas);        n=read();m=read();        cnt=0;memset(h,0,sizeof(h));        double l=0,r=0;        for(int i=1;i<=m;i++) u=read(),v=read(),w=read(),ins(u,v,w),r=max(r,w);        if(!spfanc(r+1)) puts("No cycle found.");        else{            while(r-l>eps){                double mid=(l+r)/2;                if(spfanc(mid)) r=mid;                else l=mid;            }            printf("%.2f\n",l);        }    }}

 

UVA11090 Going in Cycle!! [spfa负环]