您的位置:首页 > 其它

BZOJ1486: [HNOI2009]最小圈

2016-08-19 20:02 375 查看
Description





Input

Output

Sample Input

4 5

1 2 5

2 3 5

3 1 5

2 4 3

4 1 3

Sample Output

3.66666667

题解:

01分数规划。。就是用来求两个Σ的比值用的,建立关系后跑最短路即可,具体可参见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN=10001;
const int INF=1e9;
struct xx
{
int to,nxt;
double w;
}e[MAXN];
int head[MAXN];
double dist[MAXN],w[MAXN];
int u[MAXN],v[MAXN];
int cnt,n,E;
bool flag;
bool visit[MAXN];
void add(int x,int y,double z)
{
cnt++;
e[cnt].to=y;
e[cnt].nxt=head[x];
e[cnt].w=z;
head[x]=cnt;
}
void dfs(int x)
{
int i;
visit[x]=1;
for(i=head[x];i;i=e[i].nxt)
{
if(dist[e[i].to]>dist[x]+e[i].w)
{
if(visit[e[i].to])
{flag=1;break;}
else {
dist[e[i].to]=dist[x]+e[i].w;
dfs(e[i].to);
}
}
}
visit[x]=0;
}
bool check(double x)
{
int i;
memset(head,0,sizeof(head));
memset(dist,0,sizeof(dist));
memset(visit,0,sizeof(visit));
cnt=0;
for(i=1;i<=E;i++)
add(u[i],v[i],w[i]-x);
flag=0;
for(i=1;i<=n;i++)
{
dfs(i);
if(flag) return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int i,j;
scanf("%d%d",&n,&E);
for(i=1;i<=E;i++)
scanf("%d%d%lf",&u[i],&v[i],&w[i]);
double l,r,mid;
l=-INF,r=INF;
while(l<r-0.000000001)
{
mid=(l+r)*1.0/2*1.0;
if(check(mid)) r=mid;
else l=mid;
}printf("%.8f\n",l);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  01分数规划 算法