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;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    Java中的Date类型无法赋值给数据库的datetime类型
    在HTML中改变input标签中的内容
    sizeof计算类的大小
    UML类图,转载
    大端小段详解—转载
    leetcode练习
    linux基础
    排序算法和查找算法

    链表
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9208424.html
Copyright © 2011-2022 走看看