[Maximum Flow && Point Current Limitation] HDU-2732 Leapin'Lizards

Problem Description

Input T represents T group test data, input n, d. Represents the following two matrix n rows len columns (columns are unknown). Each point of the first matrix represents the pillar, and the corresponding value represents the bearing capacity of the pillar. When the frog jumps from here, the bearing capacity will be - until 0, it will not be able to bear the frog. The second matrix L represents that frogs start here, and that there are no frogs. Ask how many frogs you have at least that can't jump out of the border. The maximum distance a frog can jump is d.

thinking

The core is to think of the maximum flow, followed by mapping. Flow limitation of dismantling points is the bearing capacity, because it can be reached between points, so drawing needs to pay attention to the direction. Note the output sample. was were

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int to, cap, next;
};
#define inf 0x3f3f3f3f
node Map[1000000];
int head[1000], vis[1000], cnt;
char s[50][50];
void add(int u, int v, int w)//Forward Star Map
{
    Map[cnt].to = v;
    Map[cnt].cap = w;
    Map[cnt].next = head[u];
    head[u] = cnt++;
    Map[cnt].to = u;
    Map[cnt].cap = 0;
    Map[cnt].next = head[v];
    head[v] = cnt++;
}
bool bfs(int s, int e)
{
    memset(vis, -1, sizeof(vis));
    queue<int> q;
    q.push(s);
    vis[s] = 0;
    while(!q.empty())
    {
        s = q.front(), q.pop();
        for(int i = head[s]; ~i; i = Map[i].next)
        {
            int to = Map[i].to, cap = Map[i].cap;
            if(vis[to] == -1 && cap)
            {
                vis[to] = vis[s] + 1;
                q.push(to);
            }
        }
    }
    if(vis[e] == -1) return 0;
    else return 1;
}
int dfs(int s, int e, int f)
{
    if(s == e) return f;
    int ans = 0;
    for(int i = head[s]; ~i; i = Map[i].next)
    {
        int to = Map[i].to, &cap = Map[i].cap;
        if(vis[to] > vis[s] && cap)
        {
            int d = dfs(to, e, min(f, cap));
            if(d)
            {
                cap -= d;
                Map[i^1].cap += d;
                f -= d;
                ans += d;
                if(!f) break;
            }
        }
    }
    if(ans) return ans;
    vis[s] = -1;
    return 0;
}
int dinic(int s, int e)//Finding the maximum flow
{
    int ans = 0;
    while(bfs(s, e))
    {
        ans += dfs(s, e, inf);
    }
    return ans;
}
double dist(node x, node y)//Distance between two points
{
    return sqrt(double((x.to - y.to)*(x.to - y.to) + (x.cap - y.cap)*(x.cap - y.cap)));
}
int main()
{
    int T, Case = 1, n, m, d, i, j, len;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d", &n, &d);
        memset(head, -1, sizeof(head));
        cnt = 0;
        vector<node> p, ins;
        for(i = 0; i < n; i++)
        {
            scanf("%s", s[i]);
            len = strlen(s[i]);
            for(j = 0; j < len; j++)
            {
                if(s[i][j] != '0')
                    p.push_back((node){i, j, s[i][j] - '0'});//Store all pillars that can bear frogs.
            }
        }
        for(i = 0; i < n; i++)
        {
            scanf("%s", s[i]);
            for(j = 0; j < len; j++)
            {
                if(s[i][j] == 'L')
                ins.push_back((node){i, j});//Store all the first frog locations
            }
        }
        int cn = n;
        n = p.size();
        for(i = 0; i < n; i++)
        {
            add(i+1, i+n+1, p[i].next);//Split point current limiting
            if((d - p[i].to >= 1) || (d - p[i].cap >= 1) || (len - p[i].cap <= d) || (cn - p[i].to <= d))//A pillar that jumps out directly.
            {
                add(i+n+1, 2*n+1, inf);
            }
            for(j = i+1; j < n; j++)
            {
                double dis = dist(p[i], p[j]);
                if(dis > d) continue;
                add(i+n+1, j+1, inf);//Edge-building and bi-directional accessibility between points
                add(j+n+1, i+1, inf);
            }
        }
        m = ins.size();
        for(i = 0; i < m; i++)
        {
            for(j = 0; j < n; j++)
            {
                if(p[j].to == ins[i].to && p[j].cap == ins[i].cap)//There were frog spots at first.
                    add(0, j+1, 1);
            }
        }
        int ans = dinic(0, 2*n+1);//Find the maximum flow and pay attention to the output format.
        if(ans == m) printf("Case #%d: no lizard was left behind.\n", Case++);
        else if(ans == m - 1) printf("Case #%d: 1 lizard was left behind.\n", Case++);
        else
        printf("Case #%d: %d lizards were left behind.\n", Case++, m - ans);
    }
}

Posted by kristinac on Fri, 08 Feb 2019 05:45:18 -0800