zoukankan      html  css  js  c++  java
  • 费用流做题记录

    BZOJ1221:http://www.lydsy.com/JudgeOnline/problem.php?id=1221

      trick:将每天用完的,和要用的分来开处理,避免花费的重叠计算,也就是拆点

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 4e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e7;
    
    
    int na[N],ans,ans1,S,T,head[N],cnt = 1,n,dis[N],q[N],inq[N],from[N],f,fA,fB;
    struct {
        int from,to,next,c,v;
    }e[N * 2];
    void ins(int u,int v,int w,int c) {
        cnt++;
        e[cnt].from = u;
        e[cnt].to = v;
        e[cnt].v = w;
        e[cnt].c = c;
        e[cnt].next = head[u];
        head[u] = cnt;
    }
    void insert(int u,int v,int w,int c) {
        ins(u,v,w,c);ins(v,u,0,-c);
    }
    int spfa() {
        for(int i = 0; i <= T; ++i) dis[i] = inf;
        int t = 0,w = 1;
        dis[S] = q[S] = S;
        inq[S] = 1;
        while(t!=w) {
            int now = q[t++];
            if(t == 200001) t = 0;
            for(int i = head[now]; i; i = e[i].next) {
                if(e[i].v&&dis[e[i].to] > dis[now] + e[i].c)
                {
                    from[e[i].to] = i;
                    dis[e[i].to] = dis[now] + e[i].c;
                    if(!inq[e[i].to]) {
                        inq[e[i].to] = 1;
                        q[w++] = e[i].to;
                        if(w == 200001) w = 0;
                    }
                }
            }
            inq[now] = 0;
        }
        if(dis[T] >= inf) return 0;
        return 1;
    }
    void mcf() {
        int i = from[T],x=inf;
        while(i) {
            x = min(e[i].v,x);
            i = from[e[i].from];
        }
        i = from[T];
        ans1 = x;
        while(i) {
            e[i].v -= x;
            e[i^1].v += x;
            ans += e[i].c*x;
            i = from[e[i].from];
        }
    }
    int a,b;
    int main()
    {
        cnt = 1;
        memset(head,0,sizeof(head));
        scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fA,&fB);
        S = 0,T = 3*n;
        for(int i = 1; i <= n; ++i){
            scanf("%d",&na[i]);
            insert(S,i,inf,0);
            insert(S,i+n,inf,f);
            insert(i+n,T,na[i],0);
            if(i + 1 <= n)
                insert(i,i+1,inf,0);
            if(i + a + 1 <= n)
                insert(i,n+i+a+1,inf,fA);
            if(i + b + 1 <= n)
                insert(i,n+i+b+1,inf,fB);
        }
        ans = 0,ans1 = 0;
        while(spfa()) mcf();
        printf("%d
    ",ans);
        return 0;
    }
    BZOJ1221

    BZOJ2424: [HAOI2010]订货:http://www.lydsy.com/JudgeOnline/problem.php?id=2424

        trick:拆点

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 4e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e7;
    
    
    int ans,ans1,cnt,head[N],from[N],dis[N],inq[N],q[N],S,T;
    struct ss{
        int from,to,next,c,v;
    }e[N * 2];
    void ins(int u,int v,int w,int c) {
        cnt++;
        e[cnt].from = u;
        e[cnt].to = v;
        e[cnt].v = w;
        e[cnt].c = c;
        e[cnt].next = head[u];
        head[u] = cnt;
    }
    void insert(int u,int v,int w,int c) {
        ins(u,v,w,c);ins(v,u,0,-c);
    }
    int spfa() {
        for(int i = 0; i <= T; ++i) dis[i] = inf;
        int t = 0,w = 1;
        dis[S] = 0;
        q[t] = S;
        inq[S] = 1;
        while(t != w) {
            int now = q[t++];
            if(t == 200001) t = 0;
            for(int i = head[now]; i; i = e[i].next){
                if(e[i].v && dis[e[i].to] > dis[now] + e[i].c) {
                    from[e[i].to] = i;
                    dis[e[i].to] = dis[now] + e[i].c;
                    if(!inq[e[i].to]) {
                        inq[e[i].to] = 1;
                        q[w++] = e[i].to;
                        if(w == 200001) w = 0;
                    }
                }
            }
            inq[now] = 0;
        }
        if(dis[T] >= inf) return 0;
        return 1;
    }
    void mcf() {
        int i = from[T],x = inf;
        while(i) {
            x = min(e[i].v, x);
            i = from[e[i].from];
        }
        i = from[T];
        ans1 = x;
        while(i) {
          e[i].v -= x;
          e[i^1].v += x;
          ans += e[i].c * x;
          i = from[e[i].from];
        }
    }
    int n,m,s,x;
    int main() {
        cnt = 1;
        memset(head,0,sizeof(head));
        scanf("%d%d%d",&n,&m,&s);
        T = 2*n+1,S = 0;
        for(int i = 1; i <= n; ++i) {
            scanf("%d",&x);
            insert(i+n,T,x,0);
            insert(i,i+n,inf,0);
        }
        for(int i = 1; i <= n; ++i) {
            scanf("%d",&x);
            insert(S,i,inf,x);
            if(i+1<=n)insert(i,i+1,s,m);
        }
        ans1 = 0,ans = 0;
        while(spfa()) mcf();
        cout<<ans<<endl;
        return 0;
    }
    BZOJ2424

    BZOJ3171: [Tjoi2013]循环格

     trick:每个点的入度 = 出度 = 1,所以,将每个点拆点

            S向每个点连容量1费用0的边

        每个点拆出的点向T连容量1,费用0的边

        每个格子向四周连费用0或1的边

    HDU5988 http://acm.hdu.edu.cn/showproblem.php?pid=5988

       trick:第一次走这条边的话,我们拆边就行了

         ans = 1 - 最大不能破坏概率

        不能破坏概率 = (1-p1)*(1-p2)*(……); ————》 2^(log2((1-p1)+log2(1-p2)+log2(……));

        基础费用流

        需要不能破坏概率最大,就将   -( log2((1-p1)+log2(1-p2)+log2(……) ) 求最小, 边费用 就放-log(1-p);就OK

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const double eps = 0.000001;
    const int N = 6e5+10, M = 1e3+20, mod = 1e9+7,inf = 2e9;
    int cnt,head[N],from[N],inq[N],q[N],S,T;
    double ans1,ans,dis[N];
    struct ss{
        int from,to,next,v;
        double c;
    }e[N * 2];
    void ins(int u,int v,int w,double c) {
        cnt++;
        e[cnt].from = u;
        e[cnt].to = v;
        e[cnt].v = w;
        e[cnt].c = c;
        e[cnt].next = head[u];
        head[u] = cnt;
    }
    void insert(int u,int v,int w,double c) {
        ins(u,v,w,c);ins(v,u,0,-c);
    }
    int spfa() {
        for(int i = 0; i <= T; ++i) dis[i] = 1.0*inf,from[i] = -1;
        int t = 0,w = 1;
        dis[S] = 0;
        from[S] = 0;
        q[t] = S;
        inq[S] = 1;
        while(t != w) {
            int now = q[t++];
            for(int i = head[now]; i; i = e[i].next){
                if(e[i].v && dis[e[i].to] - dis[now]-e[i].c> eps ) {
                    from[e[i].to] = i;
                    dis[e[i].to] = dis[now] + e[i].c;
                    if(!inq[e[i].to]) {
                        inq[e[i].to] = 1;
                        q[w++] = e[i].to;
                    }
                }
            }
            inq[now] = 0;
        }
        if(from[T] == -1) return 0;
        return 1;
    }
    
    void mcf() {
        int i = from[T],x = inf;
        while(i) {
            x = min(e[i].v, x);
            i = from[e[i].from];
        }
        i = from[T];
        while(i) {
          e[i].v -= x;
          e[i^1].v += x;
          ans += e[i].c*x;
          i = from[e[i].from];
        }
    }
    int n,m,x,y,w,Ts;
    double p;
    int main() {
        scanf("%d",&Ts);
        while(Ts--) {
            scanf("%d%d",&n,&m);
            S = 0,T = n+1;
            cnt = 1;
            memset(head,0,sizeof(head));
            for(int i = 1; i <= n; ++i) {
                scanf("%d%d",&x,&y);
                if(x > y)insert(S,i,x-y,0);
                if(y > x)insert(i,T,y-x,0);
            }
            for(int i = 1; i <= m; ++i) {
                scanf("%d%d%d%lf",&x,&y,&w,&p);
                if(w >= 1) insert(x,y,1,0);
                if(w > 1) insert(x,y,w-1,-log2(1-p));
            }
            ans = 0;
            while(spfa()) mcf();
            printf("%.2f
    ",1-pow(2.0,-ans));
        }
        return 0;
    }
    HDU5988
  • 相关阅读:
    200. Number of Islands
    [Leetcode] 70. Climbing Stairs Java
    LeetCode 64. Minimum Path Sum Java
    LeetCode 63. Unique Paths II Java
    LeetCode 62. Unique Paths Java
    [LeetCode 241] Different Ways to Add Parentheses Java
    LeetCode 240. Search a 2D Matrix II Java
    LeetCode 215. Kth Largest Element in an Array Java
    LeetCode 169. Majority Element Java
    LeetCode 53. Maximum Subarray Java
  • 原文地址:https://www.cnblogs.com/zxhl/p/6832392.html
Copyright © 2011-2022 走看看