标签:leapin lizards hdu 2732 最大流
4 3 1 1111 1111 1111 LLLL LLLL LLLL 3 2 00000 01110 00000 ..... .LLL. ..... 3 1 00000 01110 00000 ..... .LLL. ..... 5 2 00000000 02000000 00321100 02000000 00000000 ........ ........ ..LLLL.. ........ ........
Case #1: 2 lizards were left behind. Case #2: no lizard was left behind. Case #3: 3 lizards were left behind. Case #4: 1 lizard was left behind.
思路:首先将有柱子的点拆成两个,权为承受力,增加超级源点和汇点,‘L’和源点相连,权为1,能一次跳出去的柱子和汇点相连,权为INF,然后能相互到达的柱子之间连边,权为INF。这一题要注意蜥蜴能跳的不只是四个方向,360度任何方向都行,只要两个柱子之间的距离小于d。最后注意输出。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 10005
#define MAXN 50005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;
struct Edge{
    int u,v,cap,next;
}edge[MAXN];
int n,d;
int dir[4][2]={0,1,0,-1,-1,0,1,0};
int head[maxn],level[maxn],cur[maxn];
int num,cnt,all;
char MP[25][25];
int mp[25][25];
int number[25][25];
void init()
{
    cnt=0;
    num=0;
    all=0;
    mem(head,-1);
}
void addedge(int u,int v,int w)
{
    edge[num].u=u; edge[num].v=v; edge[num].cap=w; edge[num].next=head[u]; head[u]=num++;
    edge[num].u=v; edge[num].v=u; edge[num].cap=0; edge[num].next=head[v]; head[v]=num++;
}
bool bfs(int s,int t)
{
    mem(level,-1);
    queue<int>Q;
    level[s]=0;
    Q.push(s);
    while (!Q.empty())
    {
        int u=Q.front(); Q.pop();
        for (int i=head[u];i+1;i=edge[i].next)
        {
            int v=edge[i].v;
            if (level[v]==-1&&edge[i].cap>0)
            {
                level[v]=level[u]+1;
                Q.push(v);
            }
        }
    }
    return level[t]!=-1;
}
int dfs(int u,int t,int f)
{
    if (u==t) return f;
    for (int &i=cur[u];i+1;i=edge[i].next)
    {
        int v=edge[i].v;
        if (edge[i].cap>0&&level[v]==level[u]+1)
        {
            int d=dfs(v,t,min(f,edge[i].cap));
            if (d>0)
            {
                edge[i].cap-=d;
                edge[i^1].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
int dinic(int s,int t,int cnt)
{
    int flow=0;
    while (bfs(s,t))
    {
        for (int i=0;i<=cnt;i++) cur[i]=head[i];
        int f;
        while ((f=dfs(s,t,INF))>0)
            flow+=f;
    }
    return flow;
}
int main()
{
    int i,j,k,p,t,cas=0;
    sf(t);
    while (t--)
    {
        init();
        int len;
        sff(n,d);
        for (i=0;i<n;i++)
        {
            scanf("%s",MP[i]);
            len=strlen(MP[i]);
            for (j=0;j<len;j++)
            {
                mp[i][j]=MP[i][j]-'0';
                number[i][j]=++cnt;
            }
        }
        mem(MP,0);
        for (i=0;i<n;i++)
            scanf("%s",MP[i]);
        int t=2*cnt+1;
        for (i=0;i<n;i++)
        {
            for (j=0;j<len;j++)
            {
                if (mp[i][j])
                {
                    if (i<d||j<d||n-i<=d||len-j<=d)
                        addedge(number[i][j]+cnt,t,INF);
                    addedge(number[i][j],number[i][j]+cnt,mp[i][j]); //拆点
                    for (k=0;k<n;k++)
                    {
                        for (p=0;p<len;p++)
                        {
                            int dx=abs(i-k);
                            int dy=abs(j-p);
                            double mm=sqrt(dx*dx*1.0+dy*dy*1.0);
                            if (mm>d) continue;
                            addedge(number[i][j]+cnt,number[k][p],INF);
                        }
                    }
                }
                if (MP[i][j]=='L')
                {
                    addedge(0,number[i][j],1);
                    all++;
                }
            }
        }
        int s=dinic(0,t,t+1);
        int ans=all-s;
        if (!ans)
            printf("Case #%d: no lizard was left behind.\n",++cas);
        else if (ans==1)
            printf("Case #%d: 1 lizard was left behind.\n",++cas);
        else
            printf("Case #%d: %d lizards were left behind.\n",++cas,ans);
    }
    return 0;
}
Leapin' Lizards (hdu 2732 最大流)
标签:leapin lizards hdu 2732 最大流
原文地址:http://blog.csdn.net/u014422052/article/details/45116963