zoukankan      html  css  js  c++  java
  • ZOJ 3613 Wormhole Transport

    ZOJ_3613

        这个题目由于要求一个资源只能供给一个工厂,实际上隐含要求每个连通块里面工厂数大于或等于资源数,否则就会有部分资源是无用的,就会增加没必要的代价。这样如果在最后dp的时候加入这个隐含条件,就可以用统计连通块内的资源数来代替统计可以工作的工厂数。

        另外推荐一个感觉讲这类问题讲得比较好的一个博客:http://endlesscount.blog.163.com/blog/static/821197872012525113427573/

    #include<stdio.h>
    #include<string.h>
    #define MAXD 210
    #define MAXM 10010
    #define ST 266
    #define MAXQ 2000010
    #define INF 0x3f3f3f3f
    const int Q = 2000000;
    int N, M, nn, fn, sn, first[MAXD], e, next[MAXM], v[MAXM], w[MAXM];
    int bit[MAXD], q[MAXQ], inq[MAXD][ST], front, rear;
    int f[MAXD][ST], dp[ST];
    int sum[10];
    struct Planet
    {
        int a, b;
    }p[MAXD];
    void add(int x, int y, int z)
    {
        v[e] = y, w[e] = z;
        next[e] = first[x], first[x] = e ++;
    }
    void init()
    {
        int i, j, k, x, y, z;
        fn = sn = 0;
        for(i = 1; i <= N; i ++)
            scanf("%d%d", &p[i].a, &p[i].b), fn += p[i].a > 0, sn += p[i].b;
        nn = 1 << fn + sn;
        memset(bit, 0, sizeof(bit));
        for(i = 1, k = 0; i <= N; i ++) if(p[i].a) sum[k] = p[i].a, bit[i] |= 1 << (k ++);
        for(i = 1; i <= N; i ++) if(p[i].b) bit[i] |= 1 << (k ++);
        
        memset(f, 0x3f, sizeof(f));
        for(i = 1; i <= N; i ++) if(bit[i]) f[i][bit[i]] = 0;
        
        memset(first, -1, sizeof(first));
        e = 0;
        scanf("%d", &M);
        for(i = 0; i < M; i ++)
        {
            scanf("%d%d%d", &x, &y, &z);
            add(x, y, z), add(y, x, z);    
        }
    }
    inline int Min(int x, int y)
    {
        return x < y ? x : y;
    }
    void spfa()
    {
        int i, x, st, y, nst;
        while(front != rear)
        {
            x = q[front] & 255, st = q[front] >> 8, inq[x][st] = 0;
            ++ front > Q ? front = 0 : 0;
            for(i = first[x]; i != -1; i = next[i])
            {
                y = v[i], nst = st | bit[y];
                if(f[x][st] + w[i] < f[y][nst])
                {
                    f[y][nst] = f[x][st] + w[i];
                    if(nst == st && !inq[y][nst])
                    {
                        q[rear ++] = nst << 8 | y, inq[y][nst] = 1;
                        rear > Q ? rear = 0 : 0;
                    }
                }
            }
            
        }    
    }
    bool check(int st)
    {
        int i, n = 0;
        for(i = 0; i < fn; i ++) if(st & 1 << i) n += sum[i];
        for(; i < fn + sn; i ++) if(st & 1 << i) -- n;
        return n >= 0;
    }
    void update(int st, int c, int &num, int &cost)
    {
        int i, n = 0;
        for(i = 0; i < sn; i ++) if(st & 1 << i + fn) ++ n;
        if(n > num || (n == num && c < cost))
            num = n, cost = c;    
    }
    void solve()
    {
        int i, j, k, num, cost;
        front = rear = 0;
        for(i = 0; i < nn; i ++)
        {
            for(j = 1; j <= N; j ++)
            {
                for(k = i - 1 & i; k; k = k - 1 & i)
                    f[j][i] = Min(f[j][i], f[j][k | bit[j]] + f[j][i - k | bit[j]]);
                if(f[j][i] < INF)
                    q[rear ++] = i << 8 | j, inq[j][i] = 1;
                rear > Q ? rear = 0 : 0;
            }
            spfa();
        }
        for(i = 0; i < nn; i ++)
        {
            dp[i] = INF;
            for(j = 1; j <= N; j ++)
                dp[i] = Min(dp[i], f[j][i]);
        }
         num = 0, cost = 0;
        for(i = 0; i < nn; i ++)
            if(check(i))
            {
                for(j = i - 1 & i; j; j = j - 1 & i)
                    if(check(j) && check(i - j))
                        dp[i] = Min(dp[i], dp[j] + dp[i - j]);
                if(dp[i] < INF)
                    update(i, dp[i], num, cost);
            }
        
        printf("%d %d\n", num, cost);
    }
    int main()
    {
        while(scanf("%d", &N) == 1)
        {
            init();
            solve();    
        }    
        return 0;    
    }
  • 相关阅读:
    DNS 壓力測試
    2008IT技术精英年会数据库分论坛热点扫描
    DOS command
    说说大型高并发高负载网站的系统架构
    DNS Server &Bind的配置与使用
    IoC 容器和Dependency Injection 模式
    Inversion of Control Containers and the Dependency Injection pattern
    Windows 2003网络负载均衡的实现
    UVA 10369 Arctic Network
    UVA 10397 Connect the Campus
  • 原文地址:https://www.cnblogs.com/staginner/p/2620546.html
Copyright © 2011-2022 走看看