zoukankan      html  css  js  c++  java
  • BZOJ 4501 旅行


    题目大意 : http://www.lydsy.com/JudgeOnline/problem.php?id=4501


    首先对于每一个节点,如果f[u] max , 那么每一个 v 都应取到相应的max,那么我们可以按拓扑序逆序(也就是dfs序的逆序) 先算出来每一个f[v],然后再考虑每一个节点的更新,按题意来说,f[u]=f[v]+1的最大值,由于是分式,我们考虑用01分数规划搞,我们设当前二分出来的值为mid , 则应满足 f[v] + 1 - 边数×mid >0 ,由于有限制条件,即有y边必须有x,就是一个典型的最小割了

    #include <bits/stdc++.h>
    using namespace std;
    const double eps = 1e-7;
    const int MAXN = 50005,MAXM = 500005,S = 0,T = 5001,inf = 0x7fffffff;
    bool vis[MAXN];
    int n,m,k; double f[MAXN];
    vector<int>G[MAXN];
    
    
    template<typename _t>
    inline _t read(){
        _t x=0,f=1;
        char ch=getchar();
        for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
        return x*f;
    }
    
    struct Max_flow{
        int first[MAXN],e,d[MAXN],Q[MAXN];
        Max_flow(){clear();}
        struct edge{
            int u,v,next,id;double w;
        }a[MAXM];
    
        inline void clear(){
            memset(first,0,sizeof first); e = 2;
        }
        inline void add(int u,int v,int w){
            a[e].u = u;a[e].v = v;a[e].id = w;
            a[e].next = first[u];first[u] = e++;
        }
        inline void add(int u,int v,double w){
            a[e].u = u;a[e].v = v;a[e].w = w;
            a[e].next = first[u];first[u] = e++;
        }
    
        inline void push(int u,int v,double w){
            add(u,v,w);add(v,u,0.0);
        }
    
        inline bool bfs(){
            memset(d,-1,sizeof d); d[S] = 0;
            int l = 0,r = 1;Q[l] = S;
            while(l<r) {
                int u = Q[l++];
                for(int i = first[u];i;i=a[i].next) 
                    if(d[a[i].v] == -1 && a[i].w) d[a[i].v] = d[u] + 1,Q[r++] = a[i].v;
            }
            return d[T] != -1;
        }
    
        inline double dfs(int u,double cap) {
            if(u == T || cap == 0) return cap;
            double Ans = 0.0;
            for(int i = first[u];i;i=a[i].next) {
                register int v = a[i].v; double w = a[i].w;
                if(d[v] == d[u] + 1 && w) {
                    w = dfs(v,min(w,cap - Ans));
                    Ans += w;
                    a[i].w -= w;
                    a[i^1].w += w;
                    if(Ans == cap) return Ans;
                }
            }
            if(Ans == 0) d[u] = -1;
            return Ans;
        }
    
        inline double dinic(){
            double Ans = 0.0;
            while(bfs()) Ans += dfs(S,inf);
            return Ans;
        }
    
        inline void build_limit(int u){
            int sz = G[u].size();
            for(int i = 0;i<sz;i++) push(u,G[u][i],inf); 
        }
    
        inline void __dfs__(int);
    }QAQ,QWQ;
    
    inline void Max_flow::__dfs__(int u){
        if(vis[u]) return; vis[u] = 1;
        double l = 0.0,r = 0.0,Ans,mid;
        for(int i = first[u];i;i=a[i].next) {
            __dfs__(a[i].v);
            r = max(r,f[a[i].v] + 1.0);
        }
        while(l+1e-7<r) {
            Ans = 0.0; mid = (l + r)/2.0; QWQ.clear();
            for(int i = first[u];i;i=a[i].next) {
                register int v = a[i].v; QWQ.build_limit(a[i].id);
                if(f[v] + 1 < mid)  QWQ.push(S,a[i].id,mid - f[v] - 1);
                else QWQ.push(a[i].id,T,f[v] + 1 - mid),Ans += f[v] + 1 - mid;
            }
            if(Ans > QWQ.dinic()) f[u] = mid , l = mid;
            else r = mid;
        }
        // f[u] = max(f[v] + 1 / num > L)
        // --> f[v] + 1 - num * L > 0;
        // --> sigema(f[v] + 1 - num) > 0;
    }
    
    int main(){
        n = read<int>();m = read<int>(); k = read<int>();
        for(int i = 1;i<=m;i++) {
            register int u = read<int>(),v = read<int>();
            QAQ.add(u,v,i); 
        }
        for(int i = 1;i<=k;i++) {
            register int u = read<int>(),v = read<int>();
            G[v].push_back(u);
        }
        QAQ.__dfs__(1);
        printf("%lf
    ",f[1]);
        return 0;
    }
  • 相关阅读:
    [转]C# 常用字符串加密解密方法
    ADO.net商机题目
    ADO.net属性拓展
    实体类,数据访问类应用
    实体类,数据访问类.字符串攻击.防攻击
    ADO.net增删改的应用
    ADO.net增删改查
    css——层叠样式表
    标题栏小图标、锚点、滚动效果、视频插入、音乐插入
    HTML——超文本标记语言(表单及12个表单元素)
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738472.html
Copyright © 2011-2022 走看看