BZOJ1486: [HNOI2009]最小圈

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章