
标签:
二分答案+dfs判负圈。将边值减去m,如果存在负圈则有更小的环存在。注意边界。不用spfa的原因是这不是单源最短路?。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define op() clr(head,0);pt=edges;
#define qwq(x) for(edge *o=head[x];o;o=o->next)
int read(){
int x=0;char c=getchar();bool f=true;
while(!isdigit(c)) {
if(c==‘-‘) f=false;c=getchar();
}
while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
return f?x:-x;
}
const int nmax=3005;
const int maxn=10005;
const double inf=0x7f7f7f7f;
const double eps=1e-9;
struct edge{
int to;double dist;edge *next;
};
edge edges[maxn],*pt,*head[nmax];
int vis[nmax],n,m;double d[nmax];
void add(int u,int v,double d){
pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
}
void init(){
op();
n=read(),m=read();
rep(i,m) {
int u=read(),v=read();double d;scanf("%lf",&d);
add(u,v,d);
}
}
bool dfs(int x){
vis[x]=true;
qwq(x) if(d[o->to]>d[x]+o->dist){
if(!vis[o->to]) {
d[o->to]=d[x]+o->dist;
if(dfs(o->to)) return true;
}
else return true;
}
vis[x]=false;
return false;
}
bool check(double x){
rep(i,n) qwq(i) o->dist-=x;
clr(vis,0);clr(d,0);
rep(i,n) if(dfs(i)) return true;
return false;
}
void work(){
double l=-1e7,r=1e7;
//double l=-inf,r=inf;
while(r-l>eps){
double mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
rep(i,n) qwq(i) o->dist+=mid;
}
printf("%.8lf\n",l);
}
int main(){
init();work();return 0;
}

标签:
原文地址:http://www.cnblogs.com/fighting-to-the-end/p/5675231.html