题目:
https://uva.onlinejudge.org/external/110/11090.pdf
//by yskysker123
int n,m;
double ans;
struct Edge
{
int from,to;
double w;
Edge(){}
Edge(int from,int to,double w):from(from),to(to),w(w){}
};
vector<Edge>edges;
vector<int >G[maxn];
inline void add_edge(int x,int y,double w)
{
edges.push_back(Edge(x,y,w));
int m=edges.size();
G[x].push_back(m-1);
}
inline void init()
{
edges.clear();
for(int i=1;i<=n;i++)
G[i].clear();
}
bool inq[maxn];
int cnt[maxn];
double d[maxn];
bool SPFA()
{
queue<int > q;
memset(inq, 0, sizeof(inq));
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; i++)
{ d[i] = 0; inq[0] = true; q.push(i); }
while(!q.empty())
{
int x=q.front();q.pop();
inq[x]=0;
for(int i=0;i<G[x].size();i++)
{
int id=G[x][i];
Edge &e=edges[id];
int y=e.to;
if( d[y]>d[x]+e.w )
{
d[y]=d[x]+e.w;
if( !inq[y])
{
inq[y]=1;
q.push(y);
if(++cnt[y]>n)
return true;
}
}
}
}
return false;
}
bool test(double del)
{
int m=edges.size();
for(int i=0;i<m;i++)
{
Edge &e=edges[i];
e.w-=del;
}
bool ret=SPFA();
for(int i=0;i<m;i++)
{
Edge &e=edges[i];
e.w+=del;
}
return ret;
}
int main()
{
int T,kase=0;scanf("%d",&T);
int x,y;double z;
while(T--)
{
scanf("%d%d",&n,&m);
init();
double t=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%lf",&x,&y,&z);
t=max(t,z);
add_edge(x,y,z);
}
printf("Case #%d: ",++kase);
if( !test(t+0.001)) //如果没有这一步,而直接在二分中判断有没有 mid使之存在负环的,那么wa,原因不明
puts("No cycle found.");
else
{
double le=0,ri=t;
double ans=t; //之前把ans赋初值为INF,这样是不对的,如果二分范围太大 最后有些值可能满足判断条件,但是实际上不存在这种情况
while(ri-le>1e-5)
{
double mid=le + (ri-le)/2;
if(test(mid))
{
ri=mid;
ans=min(ans,mid);
}
else le=mid;
}
printf("%.2lf\n", ans);
}
}
return 0;
}
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-7
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson num<<1,le,mid
#define rson num<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
using namespace std;
//const int INF= ;
typedef long long ll;
const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn=50+10 ;
//const int maxm= ;