zoukankan      html  css  js  c++  java
  • 《2174: Leapin' Lizards》

    这题太妙了。

    一开始一直在想怎么bfs和记忆化搜索。

    正确的思路:把最外面看成源点,汇点对每个人建边,然后柱子的限制对自己拆点建边(限制做容量)。

    然后超级汇点对每个人连边。最后要对满足条件的柱子之间建边即可。

    这里输出巨坑。0 和 1 和 >1的输出都不一样,找了好久(出题人大气层)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int N = 1e4 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9+7;
    #define pi acos(-1)
    #define INF 1e9
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
    }
    using namespace FASTIO;
    
    int n,m,d,a[25][25];
    int s,t,cnt = -1;
    int head[N],dep[N],cur[N];
    struct Node{int to,dis,next;}e[M<<2];
    inline void add(int u,int v,int w)
    {
        e[++cnt].to = v,e[cnt].dis = w,e[cnt].next = head[u],head[u] = cnt;
        e[++cnt].to = u,e[cnt].dis = 0,e[cnt].next = head[v],head[v] = cnt;
    }
    bool bfs()//分层
    {
        queue<int> Q;
        memset(dep,-1,sizeof(dep));
        dep[s] = 0;
        Q.push(s);
        while(!Q.empty())
        {
            int u = Q.front();
            Q.pop();
            for(int i=head[u];i!=-1;i=e[i].next)
            {
                int y = e[i].to,d = e[i].dis;
                if(dep[y] == -1 && d > 0)
                {
                    dep[y] = dep[u]+1;
                    Q.push(y);
                }
            }
        }
        return dep[t] != -1;
    }
    int dfs(int u,int flow)
    {
        int nowflow = 0,k;
        if(u == t) return flow;
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            cur[u] = i;//当前弧优化
            int y = e[i].to,d = e[i].dis;
            if((dep[y] == dep[u]+1) && d > 0)
            {
                if(k = dfs(y,min(flow-nowflow,d)))
                {
                    e[i].dis -= k;
                    e[i^1].dis += k;
                    nowflow += k;
                    if(nowflow == flow) break; 
                }
            }
        }
        if(nowflow == 0) dep[u] = -1;//炸点优化
        return nowflow;
    }
    LL solve()
    {
        LL ans = 0;
        while(bfs())
        {
            for(int i=1;i<=n;++i) cur[i] = head[i];
            ans += dfs(s,INF);
        }
        return ans;
    }
    /*s - 0
    st - i * m + j + 1;
    to - i * m + j + 1 + 1000;
    t - 2001;
    */
    struct Point{int x,y;};
    vector<Point> vec;
    int main()
    {
        int ca,tot = 0;ca = read();
        while(ca--)
        {
            n = read(),d = read();
            memset(head,-1,sizeof(head));
            cnt = -1;
            vec.clear();
            s = 0,t = 2001;
            for(int i = 0;i < n;++i) 
            {
                string ss;cin >> ss;
                m = ss.size();
                for(int j = 0;j < m;++j) a[i][j] = ss[j] - '0';
                for(int j = 0;j < m;++j)
                {
                    if(a[i][j] != 0)
                    {
                        add(i * m + j + 1,i * m + j + 1 + 1000,a[i][j]);//柱子自己的限制
                        if(min(i,abs(n - i) - 1) < d || min(j,abs(m - j) - 1) < d) add(i * m + j + 1 + 1000,t,INF);//满足条件的柱子向源点连
                        vec.push_back(Point{i,j});
                    }
                }
            }
            int num = 0;
            for(int i = 0;i < n;++i)
            {
                string ss;cin >> ss;
                for(int j = 0;j < m;++j)
                {
                    if(ss[j] == '.') continue;
                    num++;
                    add(s,i * m + j + 1,1);//汇点向全部人连.
                }
            }
            for(int i = 0;i < vec.size();++i)
            {
                int x1 = vec[i].x,y1 = vec[i].y;
                for(int j = i + 1;j < vec.size();++j)
                {
                    int x2 = vec[j].x,y2 = vec[j].y;
                    int dis = abs(x1 - x2) + abs(y1 - y2);
                    if(dis > d) continue;
                    add(x1 * m + y1 + 1 + 1000,x2 * m + y2 + 1,INF);
                    add(x2 * m + y2 + 1 + 1000,x1 * m + y1 + 1,INF);
                }
            }
            LL ans = 1LL * num - solve();
            if(ans == 0) printf("Case #%d: no lizard was left behind.
    ",++tot);
            else if(ans == 1) printf("Case #%d: 1 lizard was left behind.
    ",++tot);
            else printf("Case #%d: %lld lizards were left behind.
    ",++tot,ans);
        }
        system("pause");
        return 0;
    }
    /*
    20
    20 2
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    11111111111111111111
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    LLLLLLLLLLLLLLLLLLLL
    */
    View Code
  • 相关阅读:
    hdu4971 流-最大权闭包
    hdu4971 流-最大权闭包
    hdu4950 打怪(简单题目)
    hdu4950 打怪(简单题目)
    hdu4941 map交换行列
    hdu4941 map交换行列
    hdu4966 最小树形图(最少辅导花费)
    hdu4966 最小树形图(最少辅导花费)
    hdu4965 巧用矩阵乘法结合律
    POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14122781.html
Copyright © 2011-2022 走看看