uva11090 用spfa找负环

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;

struct my{
  int v;
  int next;
  double dist;
};

int m,n;
const int maxn=100000;
const int maxn2=100;
my bian[maxn];
int adj[maxn2];
double d[maxn];
bool inq[maxn];
int cnt[maxn];
int fa;
const double nil=99999999999999999;

void myinsert(int u,int v,double zhi){
    bian[++fa].v=v;
    bian[fa].dist=zhi;
    bian[fa].next=adj[u];
    adj[u]=fa;
}

void init(){
   memset(bian,-1,sizeof(bian));
   memset(adj,-1,sizeof(adj));
   fa=0;
}

bool spfa(){
     queue<int> q;
     for (int i=1;i<=n;i++) {
        inq[i]=false;
        d[i]=0;
        cnt[i]=0;
        q.push(i);
     }
     inq[1]=true;
     while(!q.empty()){
        int u=q.front();
        q.pop();
        inq[u]=false;
        for (int i=adj[u];i!=-1;i=bian[i].next){
            int v=bian[i].v;
            if(d[v]>d[u]+bian[i].dist){
                d[v]=d[u]+bian[i].dist;
                if(!inq[bian[i].v]){
                    q.push(bian[i].v);
                    inq[bian[i].v]=true;
                    if(++cnt[bian[i].v]>n) return true;
                }
            }
        }
    }
    return false;
}
bool test(double x){
     for (int i=1;i<=n;i++){
        for (int j=adj[i];j!=-1;j=bian[j].next){
            bian[j].dist-=x;
        }
     }
     int tt=spfa();
     for (int i=1;i<=n;i++){
        for (int j=adj[i];j!=-1;j=bian[j].next){
            bian[j].dist+=x;
        }
     }
     return tt;
}

int main(){
    int t;
    scanf("%d",&t);
    double maxx=-1000;
    int u,v;
    double zhi;
    int cas=0;
    while(t--){
            init();
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++){
            scanf("%d%d%lf",&u,&v,&zhi);
            maxx=max(zhi,maxx);
            myinsert(u,v,zhi);
        }
        printf("Case #%d: ",++cas);
        if(!test(maxx+1)) printf("No cycle found. ");
        else {
            double l,r;
            l=0;
            r=maxx;
            while(r-l>1e-3){
                double mid=l+(r-l)/2;
                if(test(mid)) r=mid;
                else l=mid;
            }
            printf("%.2lf ",l);
        }
    }
return 0;
}

原文地址:https://www.cnblogs.com/lmjer/p/8323816.html