zoukankan      html  css  js  c++  java
  • Leapin' Lizards HDU

    这道题其实不难。。。就是建图恶心了点。。。。emm。。。

    题意:

    多源多汇 + 拆边 

    青蛙跳柱子, 每根柱子都有一定的承载能力, 青蛙跳上去之后柱子的承载能力就会减一,跳到边界就能活 跳不到就over了,青蛙有一个最大的跳跃距离dis, 把每根柱子拆成两个点, 中间连一条边,为柱子的承载能力, 每个青蛙的初始位置都为一个源  边界为汇  , 建立超级源s和超级汇t , s连接所有青蛙的起点,权值为1, 边界和 距离青蛙起点小于dis的点连接t, 权值为INF,  并且建立u->u'  u'->v    的边

    看完题想建图的时候觉得暴力建图肯定会超时,然后实在想不出什么好的建图方法, 然后暴力建图, emm。。。竟然没超时。。。 还有注意output的英语语法!!!

    Dinic + 弧优化:。。。。现在只会写这个了。。。

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define maxn 1000000
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int head[maxn], d[maxn], cur[maxn];
    int n, m, s, t, dis;
    int cnt = 0;
    struct node{
        int u, v, c, next;
    }Node[maxn*2];
    
    void add_(int u, int v, int c)
    {
        Node[cnt].u = u;
        Node[cnt].v = v;
        Node[cnt].c = c;
        Node[cnt].next = head[u];
        head[u] = cnt++;
    }
    
    void add(int u, int v, int c)
    {
        add_(u,v,c);
        add_(v,u,0);
    }
    
    bool bfs()
    {
        queue<int> Q;
        mem(d,0);
        d[s] = 1;
        Q.push(s);
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop();
            for(int i=head[u]; i!=-1; i=Node[i].next)
            {
                node e = Node[i];
                if(!d[e.v] && e.c > 0)
                {
                    d[e.v] = d[e.u] + 1;
                    Q.push(e.v);
                    if(e.v == t) return 1;
                }
            }
        }
        return d[t] != 0;
    }
    
    int dfs(int u, int cap)
    {
        if(u == t || cap == 0)
            return cap;
        int ret = 0;
        for(int &i=cur[u]; i!=-1; i=Node[i].next)
        {
            node e = Node[i];
            if(d[e.v] == d[u] + 1 && e.c > 0)
            {
                int V = dfs(e.v, min(cap, e.c));
                Node[i].c -= V;
                Node[i^1].c += V;
                ret += V;
                cap -= V;
                if(cap == 0) break;
            }
        }
        return ret;
    }
    
    int Dinic()
    {
        int ans = 0;
        while(bfs())
        {
            memcpy(cur, head, sizeof(head));
            ans += dfs(s, INF);
        }
        return ans;
    }
    
    int main()
    {
        char str[50][50], map[maxn];
        int bz[25][25];
        int T, kase = 0;
        scanf("%d",&T);
        while(T--)
        {
            cnt = 0;
            int ret = 0;
            mem(bz,0);
            mem(head,-1);
            int ans = 0;
            scanf("%d%d",&n,&dis);
            for(int i=0; i<n; i++)
                scanf("%s",&str[i]);
            for(int i=0; i<n; i++)
            {
                int len = strlen(str[i]);
                if( i == 0) s = 0, t = 2 * len * n + 1;
                for(int j=0; j<len; j++)
                {
                    ans++;
                    int temp = str[i][j] - '0';
                    if(temp != 0)
                    {
                        add(ans, n*len + ans, temp);
                        if(i-dis < 0 || i+dis >=n || j-dis <0 || j+dis >= len){
                            add(n*len+ans, t, INF);
                        }
                            for(int k=-dis; k<=dis; k++)
                            {
                                for(int g=-dis; g<=dis; g++)
                                {
                                    int nx = i + k;
                                    int ny = j + g;
                                    if(nx == i && ny == j) continue;
                                    if(nx < 0 || nx >= n || ny < 0 || ny >= len || str[i][j] == '0' || abs(i-nx) + abs(j-ny) > dis)
                                        continue;
                                    add(n*len+ans, nx*len+ny+1, INF);
                                //    add(n*len+bz[nx][ny], ans, INF);
                                }
                            }
                    }
                }
            }
            for(int i=0; i<n; i++)
            {
                scanf("%s",map);
                for(int j=0; j<strlen(map); j++)
                {
                    if(map[j] == 'L')
                    {
                        ret++;
                        add(s, i*strlen(map)+j+1, 1);
                    }
                }
            }
    //        for(int i=0; i<cnt; i++)
    //            cout<< Node[i].u << "  " << Node[i].v << "  " <<Node[i].c<<endl;
    
            int op = ret - Dinic();
    //        for(int i=0; i<cnt; i++)
    //            cout<< Node[i].u << "  " << Node[i].v << "  " <<Node[i].c<<endl;
    
            if(op > 1)
                printf("Case #%d: %d lizards were left behind.
    ",++kase,op);
            else if(op == 0)
                printf("Case #%d: no lizard was left behind.
    ",++kase);
            else if(op == 1)
                printf("Case #%d: 1 lizard was left behind.
    ",++kase);
    
        }
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    关于JSON可能出现的错误,待更/todo
    mongoose的安装与使用(书签记录) 2017
    HTTP的学习记录3--HTTPS和HTTP
    HTTP的学习记录(二)头部
    HTTP(一)概述
    LeetCode 455. Assign Cookies
    LeetCode 453. Minimum Moves to Equal Array Elements
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 447. Number of Boomerangs
    LeetCode 416. Partition Equal Subset Sum
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9208424.html
Copyright © 2011-2022 走看看