FZU 2143 Board Game

这题好难。。第一次遇到这样的建图,表示是看了好多题解才懂的。

首先这是一个费用流的题,但是请注意,并不是达到最大流时候的最小费用。

首先分析每一个位置对答案做出的贡献,即a[i][j]*a[i][j]-2*a[i][j]*b[i][j]+b[i][j]*b[i][j],最后一项是个常数,所以我们只要计算前两项的总和的最小值。

a[i][j]表示的意义是对i,j这个位置的操作次数

假设操作了p次,这个点对答案做出的贡献是p*p-2*p*b[i][j]+b[i][j]*b[i][j]

假设操作了p-1次,这个点对答案做出的贡献是(p-1)*(p-1)-2*(p-1)*b[i][j]+b[i][j]*b[i][j]

第p次的贡献与第p-1次的贡献的差值是2*p-1-2*b[i][j]。

建图:

首先对矩阵间隔染上黑白两色,我们只对黑色格子进行操作,与黑色格子相邻的白色格子可以连动。

原点到每一个黑色格子连k条边,容量为1,第p条的费用是2*p-1-2*b[i][j],表示进行了第p次操作,在进行了p-1次操作的基础上,对答案的贡献新增加了2*p-1-2*b[i][j]

每一个白格子到汇点连k条边,容量为1,第p条的费用是2*p-1-2*b[i][j],意义同上。

请注意:2*p-1-2*b[i][j]这个式子是随着p增大而增大的,所以流量必然是从费用小的开始流,恰好与题目操作吻合。

黑色格子与他相邻的白格子连变,容量为INF,费用为0,这样能保证一个黑格子有流量流过的时候必然会把流量流向一个相邻白格子,与题目操作吻合。

接下里就是做一次费用流,但是请注意:

费用流算法结束的标志并不是SPFA的时候不能达到汇点!

而是当达到汇点的距离>=0的时候就结束了,这个时候答案已经最小了。

再继续流下去,答案会变大而不是减小。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;

const int maxn=200;
int n,m,k;
int b[15][15];
int id[15][15];

const int INF=0x7FFFFFFF;
struct Edge
{
    int from,to,cap,flow,cost;
};
int len,s,t;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn];
int d[maxn];
int p[maxn];
int a[maxn];
int use[maxn];
int ans;
int dir[4][2]=
{
    {1,0},
    {-1,0},
    {0,-1},
    {0,1},
};

void init()
{
    for(int i=0; i<maxn; i++) G[i].clear();
    edges.clear();
}

void Addedge(int from,int to,int cap,int cost)
{
    edges.push_back((Edge)
    {
        from,to,cap,0,cost
    });
    edges.push_back((Edge)
    {
        to,from,0,0,-cost
    });
    len=edges.size();
    G[from].push_back(len-2);
    G[to].push_back(len-1);
}

bool BellmanFord(int s,int t,int &flow,int &cost)
{

    for(int i=0; i<maxn; i++) d[i]=INF;

    memset(inq,0,sizeof(inq));
    memset(p,-1,sizeof(p));

    d[s]=0;
    inq[s]=1;
    p[s]=0;
    a[s]=INF;

    queue<int>Q;
    Q.push(s);
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        inq[u]=0;
        for(int i=0; i<G[u].size(); i++)
        {
            Edge& e=edges[G[u][i]];
            if(e.cap>e.flow&&d[e.to]>d[u]+e.cost)
            {
                d[e.to]=d[u]+e.cost;
                p[e.to]=G[u][i];
                a[e.to]=min(a[u],e.cap-e.flow);
                if(!inq[e.to])
                {
                    Q.push(e.to);
                    inq[e.to]=1;
                }
            }
        }
    }
    if(d[t]>=0) return false;
    flow+=a[t];
    cost+=d[t]*a[t];
    int u=t;
    while(u!=s)
    {
        edges[p[u]].flow+=a[t];
        edges[p[u]^1].flow-=a[t];
        u=edges[p[u]].from;
    }
    return true;
}

void Mincost (int s,int t)
{
    int flow=0,cost=0;
    while(BellmanFord(s,t,flow,cost));
    ans=ans+cost;
}

bool P(int a,int b)
{
    if(a>=1&&a<=n&&b>=1&&b<=m) return 1;
    return 0;
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int cas=1; cas<=T; cas++)
    {
        init();
        scanf("%d%d%d",&n,&m,&k);
        ans=0;
        int ID=1;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
            {
                scanf("%d",&b[i][j]);
                ans=ans+b[i][j]*b[i][j];
                id[i][j]=ID++;
            }

        s=0;
        t=n*m+1;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if((i+j)%2==1)
                {
                    for(int p=1; p<=k; p++)
                        Addedge(s,id[i][j],1,2*p-1-2*b[i][j]);

                    for(int d=0; d<4; d++)
                    {
                        int x=i+dir[d][0],y=j+dir[d][1];
                        if(P(x,y)) Addedge(id[i][j],id[x][y],INF,0);
                    }
                }
                else
                {
                    for(int p=1; p<=k; p++)
                        Addedge(id[i][j],t,1,2*p-1-2*b[i][j]);
                }
            }
        }
        Mincost(s,t);
        printf("Case %d: %d\n",cas,ans);
    }
    return 0;
}
时间: 2024-10-03 01:16:37

FZU 2143 Board Game的相关文章

FZU 2150 Fire Game(点火游戏)

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-size: 10.5000pt } h2 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: left; font-family: 宋体; font-weight: bold; font-size: 18.0000pt } h3 {

ACM: FZU 2150 Fire Game - DFS+BFS+枝剪 或者 纯BFS+枝剪

FZU 2150 Fire Game Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this boar

(FZU 2150) Fire Game (bfs)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2150 Problem Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty a

FZU Problem 2150 Fire Game (双起点BFS啊 )

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2150 Problem Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, each grid of this board is consisting of grass or just empty a

FZU Problem 2151 OOXX Game (数学啊)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2151 Problem Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning, there are N*M coins in this board with two symbol "O" or

FZU 2151 OOXX Game

OOXX Game Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice FZU 2151 Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns). At the beginning,

FZU 1096 QS Network

QS Network Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on FZU. Original ID: 1096 64-bit integer IO format: %I64d      Java class name: Main In the planet w-503 of galaxy cgb, there is a kind of intelligent creature named QS.

开源软件Review Board

开源软件, Review Board 代码审查的. https://www.reviewboard.org/

419. Battleships in a Board

Given an 2D board, count how many different battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: You receive a valid board, made of only battleships or empty slot