标签:head sharp bool else eof 等于 lib ret 最小
[BZOJ1486][HNOI2009]最小圈
试题描述


输入
见“试题描述”
输出
输入示例
4 5 1 2 5 2 3 5 3 1 5 2 4 3 4 1 3
输出示例
3.66666667
数据规模及约定
见“试题描述”
题解
分数规划,二分答案 x 后每条边的边权减去 x,若有负环则表明答案小于等于 x。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
return x * f;
}
#define maxn 3010
#define maxm 10010
#define LL long long
int n, m, head[maxn], nxt[maxm], to[maxm];
LL dist[maxm], eval[maxm];
void AddEdge(int a, int b, LL c) {
to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
return ;
}
LL d[maxn];
bool vis[maxn];
bool spfa(int u) {
vis[u] = 1;
for(int e = head[u]; e; e = nxt[e]) if(d[to[e]] >= d[u] + eval[e]) {
if(vis[to[e]]) return 1;
d[to[e]] = d[u] + eval[e];
if(spfa(to[e])) return 1;
}
vis[u] = 0;
return 0;
}
bool has_ncyc() {
memset(vis, 0, sizeof(vis));
memset(d, 0, sizeof(d));
for(int i = 1; i <= n; i++)
if(spfa(i)) return 1;
return 0;
}
int main() {
LL l = 0, r = 0;
n = read(); int M = read();
for(int i = 1; i <= M; i++) {
int a = read(), b = read(); LL c = (LL)read() * 2000000000ll;
AddEdge(a, b, c); r += c;
}
l = -r;
while(l < r) {
LL mid = l + r >> 1;
for(int i = 1; i <= m; i++) eval[i] = dist[i] - mid;
if(has_ncyc()) r = mid; else l = mid + 1;
}
printf("%.8lf\n", (double)l / 2e9);
return 0;
}
标签:head sharp bool else eof 等于 lib ret 最小
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/6871671.html