• [BZOJ3380] [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一


    Description

        很少人知道其实奶牛非常喜欢到洞穴里面去探险。
        洞窟里有N(1≤N≤100)个洞室,由M(1≤M≤1000)条双向通道连接着它们.每对洞室间
    至多只有一条双向通道.有K(1≤K≤14)个洞室,里面放有1捆干草.牛吃1捆干草,体重指数就会增加1.
        贪吃的贝茜要到洞窟里面探险.她希望能吃尽量多的干草,但每条通道有一个宽度阈值,如果体重指数超过相应的阈值,贝茜就会被卡祝她从洞窟1出发,体重指数为0.在洞里溜达一圈后,她要返回洞窟1.    那她最多能吃多少捆干草呢?注意,贝茜经过一个洞室,不一定非要吃掉里面的干草.

    Input

        第1行输入N,M,K,之后K行每行一个整数,表示在这个洞室放有一捆干草;接下来M行每行三个整数,表示一条双向通道的起点终点和宽度阈值.

    Output

     
        最多能吃掉的干草数.

    Sample Input

    6 7 5
    1
    2
    3
    4
    5
    1 2 3
    3 6 2
    6 2 10
    2 4 1
    5 1 1
    4 5 1
    1 6 1

    Sample Output

    4
     

     
    设$f[i][j]$为目前在第$i$个关键点,吃过甘草的关键点的状态是$j$是否可行。
    然后用Floyd处理出任意两点之间的路径上可以通过的最大的肥胖度。
    然后随便转移一下。
    Floyd的预处理部分貌似还不太熟悉...到底$i$相等的时候赋什么值好啊...
     
     

     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    #define reg register
    inline int read() {
        int res = 0;char ch=getchar();bool fu=0;
        while(!isdigit(ch))fu|=(ch=='-'), ch=getchar();
        while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return fu?-res:res;
    }
    #define N 105
    int n, m, K;
    int G[N][N];
    int f[105][1<<15], bin[17], cb[1<<16];
    int pos[17];
    
    int main()
    {
        n = read(), m = read(), K = read();
        for (reg int i = 1 ; i <= K ; i ++) pos[i] = read();
        memset(G, 0xcf, sizeof G);
        for (reg int i = 1 ; i <= m ; i ++)
        {
            int x = read(), y = read(), z = read();
            G[x][y] = G[y][x] = z;
        }
        for (reg int i = 1 ; i <= n ; i ++) G[i][i] = 0x3f3f3f3f;
        for (reg int k = 1 ; k <= n ; k ++)
            for (reg int i = 1 ; i <= n ; i ++)
                for (reg int j = 1 ; j <= n ; j ++)
                    if (i != j and i != k and k != j) 
                        G[i][j] = max(G[i][j], min(G[i][k], G[k][j]));
        bin[0] = 1;
        for (reg int i = 1 ; i <= 16 ; i ++) bin[i] = bin[i - 1] << 1;
        for (reg int i = 1 ; i < (1 << 16) ; i ++) cb[i] = cb[i >> 1] + (i & 1);
        for (reg int i = 1 ; i <= K ; i ++) f[i][bin[i - 1]] = 1;
        for (reg int s = 0 ; s < bin[K] ; s ++)
        {
            for (reg int i = 1 ; i <= K ; i ++)
            {
                if (!(s & bin[i - 1])) continue;
                if (!f[i][s]) continue;
                for (reg int j = 1 ; j <= K ; j ++)
                {
                    if (s & bin[j - 1]) continue;
                    if (G[pos[i]][pos[j]] >= cb[s]) f[j][s | bin[j - 1]] |= f[i][s];
                }
            }
        }
        int ans = 0;
        for (reg int s = 0 ; s < bin[K] ; s ++)
            for (reg int i = 1 ; i <= K ; i ++)
                if (s & bin[i - 1] and f[i][s]) ans = max(ans, min(G[pos[i]][1], cb[s]));
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    C语言博客作业-字符数组
    C语言博客作业--一二维数组
    个人作业5
    个人作业4
    个人作业3
    201521123072 结对编程
    软件工程 个人阅读作业2
    软件工程 个人阅读作业
    java课程设计--WeTalk(201521123072秦贞一)
    201521123072《java程序设计》第十四周学习总结
  • 原文地址:https://www.cnblogs.com/BriMon/p/9794419.html
Copyright © 2020-2023  润新知