UVA 11090 Going in Cycle!!

时间:2021-12-23 06:51:06

要求给定的图的中平均权值最小的环,注意处理自环的情况就能过了。

按照w1+w2+w3+….wn < n*ave的不等式,也就是(w1-ave) + (w2-ave) +…..(wn-ave) < 0,将每条边减去ave看是否存在负权回路,然后不断二分,由于保留两位小数,所以至少二分log(10^7)= 30次。

代码:

#include <iostream>
#include <sstream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <string>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define esp 1e-6
#define pi acos(-1.0)
#define pb push_back
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mp(a, b) make_pair((a), (b))
#define in freopen("in.txt", "r", stdin);
#define out freopen("out.txt", "w", stdout);
#define print(a) printf("%d\n",(a));
#define bug puts("********))))))");
#define stop system("pause");
#define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
#define inf 0x0f0f0f0f using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> pii;
typedef vector<pii> VII;
typedef vector<pii, int> VIII;
typedef VI:: iterator IT;
const int maxn = ; struct Edge
{
int from, to;
double dist;
}; struct Bellman_Ford
{
int n, m;
vector<Edge> edges;
VI G[maxn];
double d[maxn];
int p[maxn];
int inq[maxn];
int cnt[maxn]; void init(int n)
{
this->n = n;
for(int i = ; i < n; i++)
{
G[i].clear();
}
edges.clear();
} void add(int from, int to, double dist)
{
edges.pb((Edge)
{
from, to, dist
});
m = edges.size();
G[from].pb(m-);
}
bool negativeCircle(double L)
{
memset(cnt, , sizeof(cnt));
memset(inq, , sizeof(inq));
queue<int> q; for(int i = ; i < n; i++)
{
d[i] = ;
inq[] = ;
q.push(i);
}
while(!q.empty())
{
int u = q.front();
q.pop();
inq[u] = ;
for(int i = ; i < G[u].size(); i++)
{
Edge &e = edges[G[u][i]];
if(d[e.to] > d[u] + e.dist - L)
{
d[e.to] = d[u] + e.dist - L;
if(!inq[e.to])
{
q.push(e.to);
inq[e.to] = ;
}
if(++cnt[e.to] > n)
{
return true;
}
}
}
}
return false;
}
} solver; int main(void)
{ int T;
for(int t = scanf("%d", &T); t <= T; t++)
{
printf("Case #%d: ", t);
int n, m;
scanf("%d%d", &n, &m);
solver.init(n);
double ans = inf + ; double l = (double)inf*, r = ;
while(m--)
{
int u, v;
double w;
scanf("%d%d%lf", &u, &v, &w);
u--, v--;
if(u == v)
ans = min(ans, w);
solver.add(u, v, w);
l = min(l, w);
r = max(r, w);
}
int flag= ;
double mid = (l+r)/;
for(int i = ; i < ; i++)
{
if(solver.negativeCircle(mid))
flag = , r = mid-0.001;
else l = mid+0.001;
mid = (l+r)/;
}
if(flag)
printf("%.2f\n", min(ans, mid));
else if(ans < inf)
printf("%.2f\n", ans);
else puts("No cycle found.");
}
return ;
}