UVA1389 Hard Life (01分数规划+最大流)

洛谷

题目描述略

题解时间

$ (\frac{\Sigma EdgeCount}{\Sigma PointCount})_{max} $

是什么已经不用说了⑧

经典的01分数规划

上来先二分答案$ ans $

之后考虑判断

根据选边与选点的关系

考虑建出这样一个图:

建立源点 $ S $ 与汇点 $ P $

对于原图中的每条边看做一个点,从 $ S $ 向这个点建流量为 $ 1 $ 的边

对于原图中的每个点向 $ T $ 建流量为 $ ans $ 的边

对于原图中的每条边所代表的点,向这条边连接的两个点建流量为 $ 1 $ 的边

跑最大流, $ maxflow \leq m $ 即可

原理?

我们回顾一下柿子

$ \frac{\Sigma EdgeCount}{\Sigma PointCount} \leq ans $

转换一下就是

$ \Sigma EdgeCount-\Sigma PointCount*ans \leq 0 $

好像已经很明显了⑧

那就先这样吧(溜走)

#include
#include
#include
#include
using namespace std;
namespace LarjaIX
{
const int N=2011;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double dinf=1e8;
struct sumireko{int to,ne;double w;}e[N<<2];
int he[N],ecnt=1;
void addline(int f,int t,double w)
{
    e[++ecnt].to=t,e[ecnt].w=w;
    e[ecnt].ne=he[f],he[f]=ecnt;
    e[++ecnt].to=f,e[ecnt].w=0;
    e[ecnt].ne=he[t],he[t]=ecnt;
}
int head[N],dep[N];
queueq;
bool ins[N];
bool bfs(int sp,int ep)
{
    memcpy(head,he,sizeof(head));
    memset(dep,0x3f,sizeof(dep));
    dep[sp]=1,q.push(sp);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int ei=he[x],t=e[ei].to;ei;ei=e[ei].ne,t=e[ei].to)
        if(dep[t]==inf&&e[ei].w>eps) dep[t]=dep[x]+1,q.push(t);
    }
    return dep[ep]!=inf;
}
double dfs(int x,double lim,int ep)
{
    if(x==ep||limeps)
        {
            lim-=tmp,ret+=tmp;
            e[ei].w-=tmp,e[ei^1].w+=tmp;
            if(limeeps)
        {
            ansm=(ansl+ansr)/2;
            for(int i=1;i<=m;i++) addline(n+i,lx[i],1.0),addline(n+i,ly[i],1.0);
            for(int i=1;i<=m;i++) addline(n+m+1,n+i,1.0);
            for(int i=1;i<=n;i++) addline(i,n+m+2,ansm);
            double tmp=dinic(n+m+1,n+m+2);
            if((double)m-tmp>eps) ansl=ansm;
            else ansr=ansm;
            ecnt=1,memset(he,0,sizeof(he));
        }
        ansm=ansl;
        for(int i=1;i<=m;i++) addline(n+i,lx[i],dinf),addline(n+i,ly[i],dinf);
        for(int i=1;i<=m;i++) addline(n+m+1,n+i,1.0);
        for(int i=1;i<=n;i++) addline(i,n+m+2,ansm);
        dinic(n+m+1,n+m+2);
        bfs(n+m+1,n+m+2);
        int ans=0;
        for(int i=1;i<=n;i++) if(dep[i]!=inf) ans++;
        printf("%d\n",ans);
        for(int i=1;i<=n;i++) if(dep[i]!=inf) printf("%d\n",i);
        ecnt=1,memset(he,0,sizeof(he));
    }
    return 0;
}
}
int main(){return LarjaIX::maid();}

你可能感兴趣的:(UVA1389 Hard Life (01分数规划+最大流))