BestCoder Round #1 HDU4859 (海岸线)

http://acm.hdu.edu.cn/showproblem.php?pid=4859

海岸线

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 137    Accepted Submission(s): 76

Problem Description

欢迎来到珠海!

由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展。作为Z市的决策人,在仔细观察了Z市地图之后,你准备通过填充某些海域来扩展Z市的海岸线到最长,来吸引更多的游客前来旅游度假。为了简化问题,假设地图为一个N*M的格子,其中一些是陆地,一些是可以填充的浅海域,一些是不可填充的深海域。这里定义海岸线的长度为一个联通块陆地(可能包含浅海域填充变为的陆地)的边缘长度,两个格子至少有一个公共边,则视为联通。

值得注意的是,这里Z市的陆地区域可以是不联通的,并且整个地图都处在海洋之中,也就是说,Z市是由一些孤岛组成的,比如像,夏威夷?

你的任务是,填充某些浅海域,使得所有岛屿的海岸线之和最长。

Input

输入第一行为T,表示有T组测试数据。
每组数据以两个整数N和M开始,表示地图的规模。接下来的N行,每一行包含一个长度为M的字符串,表示地图,‘.’表示陆地,’E’表示浅海域,’D’表示深海域。

[Technical Specification]

1. 1 <= T <= 100
2. 1 <= N, M <= 47

Output

对每组数据,先输出为第几组数据,然后输出最长的海岸线长度。

Sample Input

3
2 2
EE
EE
3 3
EEE
.E.
EEE
3 3
EEE
DED
EEE

Sample Output

Case 1: 8
Case 2: 16
Case 3: 20

Hint

对于第三组样例,一种可行方案是:

.E.
D.D
.E.

这样5个孤立小岛的海岸线总长为4 * 5 = 20。

Author

[email protected]

Source

BestCoder Round #1

.... 什么也不说了http://www.kuangbin.net/archives/hdu4859这位代码很好, 这位题解很好http://blog.csdn.net/scf0920/article/details/38064593

搭配着看效果很好T T

#include <iostream>
#include <cstring>

using namespace std;

#define rep(i, n) for (int i = 0, _n = (int)(n); i < _n; i++)
#define fer(i, x, n) for (int i = (int)(x), _n = (int)(n); i < _n; i++)
#define rof(i, n, x) for (int i = (int)(n), _x = (int)(x); i-- > _x; )
#define fch(i, x) for (__typeof(x.begin()) i = x.begin(); i != x.end(); i++)
#define sz(x) (int((x).size()))
#define pb push_back
#define mkp make_pair
#define all(X) (X).begin(),(X).end()

#define X first
#define Y second

template<class T> inline void smin(T &a, T b){if(b<a)a=b;}
template<class T> inline void smax(T &a, T b){if(a<b)a=b;}

template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
template<class T> inline void CLR(T &A){A.clear();}

/** Constant List .. **/ //{
const int dx4[] = {-1, 0, 1, 0};
const int dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, 0, 1, 0 , -1 , -1 , 1 , 1};
const int dy8[] = {0, 1, 0, -1 , -1 , 1 , -1 , 1};
const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
//}

template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
template<class T> inline T min(T a, T b, T c, T d){return min(min(a, b), min(c, d));}
template<class T> inline T max(T a, T b, T c, T d){return max(max(a, b), max(c, d));}
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T cub(T a){return a*a*a;}

////////////////////////////////////////////////////////////////////////////////

const int MAXN = 10010;
const int MAXM = 100010;
struct Edge
{
    int to,next,cap,flow;
}edge[MAXM];
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
void init()
{
    tol = 0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int rw = 0)
{
    edge[tol].to = v;edge[tol].cap = w;edge[tol].next = head[u];
    edge[tol].flow = 0; head[u] = tol++;
    edge[tol].to = u;edge[tol].cap = rw;edge[tol].next = head[v];
    edge[tol].flow = 0;head[v] = tol++;
}
int sap(int start,int end,int N)
{
    memset(gap,0,sizeof(gap));
    memset(dep,0,sizeof(dep));
    memcpy(cur,head,sizeof(head));
    int u = start;
    pre[u] = -1;
    gap[0] = N;
    int ans = 0;
    while(dep[start] < N)
    {
        if(u == end)
        {
            int Min = INF;
            for(int i = pre[u];i != -1;i = pre[edge[i^1].to])
                if(Min > edge[i].cap - edge[i].flow)
                    Min = edge[i].cap - edge[i].flow;
            for(int i = pre[u];i != -1;i = pre[edge[i^1].to])
            {
                edge[i].flow += Min;
                edge[i^1].flow -= Min;
            }
            u = start;
            ans += Min;
            continue;
        }
        bool flag = false;
        int v;
        for(int i = cur[u];i != -1;i = edge[i].next)
        {
            v = edge[i].to;
            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])
            {
                flag = true;
                cur[u] = pre[v] = i;
                break;
            }
        }
        if(flag)
        {
            u = v;
            continue;
        }
        int Min = N;
        for(int i = head[u];i != -1;i = edge[i].next)
            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
            {
                Min = dep[edge[i].to];
                cur[u] = i;
            }
        gap[dep[u]]--;
        if(!gap[dep[u]])return ans;
        dep[u] = Min+1;
        gap[dep[u]]++;
        if(u != start)u = edge[pre[u]^1].to;
    }
    return ans;
}

int T,n,m;
char s[50][50];
int id[50][50];
int start,end;
int main()
{
    //freopen("in.txt","r",stdin);
    ios_base::sync_with_stdio(0);
    scanf("%d",&T);
    fer(tt,1,T+1){
        scanf("%d%d",&n,&m);
        fer(i,1,n+1) scanf("\n%s",s[i]+1);
        rep(i,n+2) s[i][0]=s[i][m+1]=‘D‘;
        rep(i,m+2) s[0][i]=s[n+1][i]=‘D‘;
        init();
        int cnt=0;
        rep(i,n+2) rep(j,m+2) id[i][j]=++cnt;
        start=0,end=cnt+1;
        int sume = 0;
        rep(i,n+2) rep(j,m+2){
            rep(k,4){
                int tx=i+dx4[k],ty=j+dy4[k];
                if(tx<0 || tx>=n+2 || ty<0 || ty>=m+2) continue;
                sume++; addedge(id[i][j],id[tx][ty],1);
            }
            if(s[i][j]!=‘E‘){
                if( ((i+j)%2==1 && s[i][j]==‘.‘) || ((i+j)%2==0 && s[i][j]==‘D‘) ) addedge(start,id[i][j],INF);
                else addedge(id[i][j],end,INF);
            }
        }
        printf("Case %d: %d\n",tt,sume/2-sap(start,end,cnt+2) );
    }
    return 0;
}
时间: 2024-08-25 17:21:49

BestCoder Round #1 HDU4859 (海岸线)的相关文章

BestCoder Round #91

传送门:http://acm.hdu.edu.cn/search.php?field=problem&key=BestCoder+Round+%2391&source=1&searchmode=source A题:给你n种字母,每种字母有个权值vali,共cnti个,现在让你在里面挑出任意数量的字符,组合成一个字符串,该字符串的权值的计算方式为val1*1+val2*2+--+valn*n,让你输出字符串最大的权值是多少.这题很容易会有一个错误的贪心,就是把val为负的舍去,然后v

BestCoder Round #65 (ZYB&#39;s Game)

ZYB's Game Accepts: 672 Submissions: 1207 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description ZYBZYBZYB played a game named NumberBombNumber BombNumberBomb with his classmates in hiking:a host keeps a

hdu5418 BestCoder Round #52 (div.2) Victor and World ( floyd+状压dp)

Problem Description After trying hard for many years, Victor has finally received a pilot license. To have a celebration, he intends to buy himself an airplane and fly around the world. There are n countries on the earth, which are numbered from 1 to

hdu 5163 Taking Bus (BestCoder Round #27)

Taking Bus                                                               Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 501    Accepted Submission(s): 203 Problem Description Bestland has a v

BestCoder Round #11 (Div. 2) 前三题题解

题目链接: huangjing hdu5054 Alice and Bob 思路: 就是(x,y)在两个參考系中的表示演全然一样.那么仅仅可能在这个矩形的中点.. 题目: Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 216    Accepted Submission(s): 166 Problem De

BestCoder Round #16

BestCoder Round #16 题目链接 这场挫掉了,3挂2,都是很sb的错误 23333 QAQ A:每个数字,左边个数乘上右边个数,就是可以组成的区间个数,然后乘的过程注意取模不然会爆掉 B:dp,dp[i][2]记录下第一长的LIS,和第二长的LIS,哎,转移的时候一个地方写挫掉了导致悲剧啊QAQ C:首先如果知道Nim游戏的,就很容易转化问题为,一些数字是否能选几个能否异或和为0,那么就是每个数字拆成40位,然后每一位异或和为0,这样就可以构造出40个方程,然后高斯消元求解,如果

BestCoder Round #11 (Div. 2) 题解

HDOJ5054 Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 302    Accepted Submission(s): 229 Problem Description Bob and Alice got separated in the Square, they agreed that if they

BestCoder Round #9

BestCoder Round #9 题目链接 A:暴力枚举一个数字,就能求出另一个数字,for一遍即可 B:博弈,判断前n - 1个开头连续1的奇偶性即可 C:先预处理出每个点对应哪几个点,每次查询计算一次即可 代码: A: #include <cstdio> #include <cstring> #include <vector> #include <set> #include <algorithm> #include <cmath&g

hdu 4956 Poor Hanamichi BestCoder Round #5(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4956 Poor Hanamichi Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7    Accepted Submission(s): 4 Problem Description Hanamichi is taking part in