• 省选模拟赛 cti


    3 cti (cti.cpp/in/out, 1s, 512MB)
    3.1 Description
    有一个 n × m 的地图, 地图上的每一个位置可以是空地, 炮塔或是敌人. 你需要操纵炮塔消灭
    敌人.
    对于每个炮塔都有一个它可以瞄准的方向, 你需要在它的瞄准方向上确定一个它的攻击位置,
    当然也可以不进行攻击. 一旦一个位置被攻击, 则在这个位置上的所有敌人都会被消灭.
    保证对于任意一个炮塔, 它所有可能的攻击位置上不存在另外一个炮塔.
    定义炮弹的运行轨迹为炮弹的起点和终点覆盖的区域. 你需要求出一种方案, 使得没有两条炮
    弹轨迹相交.
    3.2 Input Format
    第一行两个整数 n,m.
    接下来 n 行, 每行 m 个整数, 0 表示空地, −1,−2,−3,−4 分别表示瞄准上下左右的炮塔, 正整
    数 p 表示表示此位置有 p 个敌人.
    3.3 Output Format
    一行一个整数表示答案.
    3.4 Sample 1
    3.4.1 Input
    3 2
    0 9
    -4 3
    0 -1
    3.4.2 Output
    9
    3.5 Sample 2
    3.5.1 Input
    4 5
    0 0 -2 0 0
    -4 0 5 4 0
    0 -4 3 0 6
    9 0 0 -1 0
    3.5.2 Output
    12

    3.6 Constraints
    对于前 20% 的数据, n,m ≤ 5;
    对于另 20% 的数据, 朝向上下的炮塔至多有 2 个;
    对于另 20% 的数据, 至多有 6 个炮塔;
    对于 100% 的数据, 1 ≤ n,m ≤ 50, 每个位置的敌人数量 < 1000.

    分析:将题目看作炮塔和敌人“匹配”,就和比特板这道题几乎一模一样了.

       需要注意的是炮塔可以不攻击任何敌人,那么连inf的边实际上就是连0边. 

    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 55 * 55,inf = 0x7fffffff;
    int n,m,ans,a[55][55],cnt,cnt1,cnt2,S,T,pos[maxn][maxn],head[100010],to[100010],nextt[100010],w[100010],tot = 2;
    int d[100010];
    struct node
    {
        int x,y,opt;
    } shu[maxn],heng[maxn];
    
    void add(int x,int y,int z)
    {
        //cout << x << " " << y << " " << 1000 - z << endl;
        w[tot] = z;
        to[tot] = y;
        nextt[tot] = head[x];
        head[x] = tot++;
    
        w[tot] = 0;
        to[tot] = x;
        nextt[tot] = head[y];
        head[y] = tot++;
    }
    
    bool bfs()
    {
        queue <int> q;
        q.push(S);
        memset(d,-1,sizeof(d));
        d[S] = 0;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            if (u == T)
                return true;
            for (int i = head[u];i;i = nextt[i])
            {
                int v = to[i];
                if (w[i] && d[v] == -1)
                {
                    d[v] = d[u] + 1;
                    q.push(v);
                }
            }
        }
        return false;
    }
    
    int dfs(int u,int f)
    {
        if (u == T)
            return f;
        int res = 0;
        for (int i = head[u];i;i = nextt[i])
        {
            int v = to[i];
            if (d[v] == d[u] + 1 && w[i])
            {
                int temp = dfs(v,min(f - res,w[i]));
                w[i] -= temp;
                w[i ^ 1] += temp;
                res += temp;
                if (res == f)
                    return res;
            }
        }
        if (!res)
            d[u] = -1;
        return res;
    }
    
    void dinic()
    {
        while (bfs())
            ans -= dfs(S,inf);
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
            {
                scanf("%d",&a[i][j]);
                if (a[i][j] < 0)
                {
                    if (a[i][j] == -1 || a[i][j] == -2)
                    {
                        node temp;
                        temp.x = i;
                        temp.y = j;
                        temp.opt = a[i][j];
                        shu[++cnt1] = temp;
                    }
                    else
                    {
                        node temp;
                        temp.x = i;
                        temp.y = j;
                        temp.opt = a[i][j];
                        heng[++cnt2] = temp;
                    }
                }
            }
        for (int i = 1; i <= cnt1; i++)
        {
            if (shu[i].opt == -1)
                for (int j = 1; j <= shu[i].x; j++)
                    pos[i][j] = ++cnt;
            else
                for (int j = 1; j <= n - shu[i].x + 1; j++)
                    pos[i][j] = ++cnt;
        }
        for (int i = 1; i <= cnt2; i++)
        {
            if (heng[i].opt == -3)
                for (int j = 1; j <= heng[i].y; j++)
                    pos[i + cnt1][j] = ++cnt;
            else
                for (int j = 1; j <= m - heng[i].y + 1; j++)
                    pos[i + cnt1][j] = ++cnt;
        }
        ans = 1000 * (cnt1 + cnt2);
        S = ++cnt;
        T = ++cnt;
        for (int i = 1; i <= cnt1; i++)
        {
            if (shu[i].opt == -1)
            {
                for (int j = 1; j <= shu[i].x; j++)
                {
                    if (j != shu[i].x)
                        add(pos[i][j],pos[i][j + 1],1000 - a[shu[i].x - j][shu[i].y]);
                    else
                        add(pos[i][j],T,1000);
                    if (j == 1)
                        add(S,pos[i][j],1000);
                }
            }
            else
            {
                for (int j = 1; j <= n - shu[i].x + 1; j++)
                {
                    if (j != n - shu[i].x + 1)
                        add(pos[i][j],pos[i][j + 1],1000 - a[shu[i].x + j][shu[i].y]);
                    else
                        add(pos[i][j],T,1000);
                    if (j == 1)
                        add(S,pos[i][j],1000);
                }
            }
        }
        for (int i = 1; i <= cnt2; i++)
        {
            if (heng[i].opt == -3)
            {
                for (int j = 1; j <= heng[i].y; j++)
                {
                    if (j != heng[i].y)
                        add(pos[i + cnt1][j],pos[i + cnt1][j + 1],1000 - a[heng[i].x][j]);
                    else
                        add(pos[i + cnt1][j],T,1000);
                    if (j == 1)
                        add(S,pos[i + cnt1][j],1000);
                }
            }
            else
            {
                for (int j = 1; j <= m - heng[i].y + 1; j++)
                {
                    if (j != m - heng[i].y + 1)
                        add(pos[i + cnt1][j],pos[i + cnt1][j + 1],1000 - a[heng[i].x][m - j + 1]);
                    else
                        add(pos[i + cnt1][j],T,1000);
                    if (j == 1)
                        add(S,pos[i + cnt1][j],1000);
                }
            }
        }
        for (int i = 1; i <= cnt1; i++)
            for (int j = 1; j <= cnt2; j++)
            {
                int X,Y;
                if (shu[i].opt == -1 && heng[j].opt == -4) //上右
                {
                    if (shu[i].x < heng[j].x || shu[i].y < heng[j].y)
                        continue;
                    X = heng[j].x;
                    Y = shu[i].y;
                    int temp1 = shu[i].x - X;
                    int temp2 = m - Y + 2;
                    add(pos[i][temp1],pos[j + cnt1][temp2],1000);
                }
                if (shu[i].opt == -1 && heng[j].opt == -3) //上左
                {
                    if (shu[i].x < heng[j].x || shu[i].y > heng[j].y)
                        continue;
                    X = heng[j].x;
                    Y = shu[i].y;
                    int temp1 = shu[i].x - X;
                    int temp2 = Y + 1;
                    add(pos[i][temp1],pos[j + cnt1][temp2],1000);
                }
                if (shu[i].opt == -2 && heng[j].opt == -4) //下右
                {
                    if (shu[i].y < heng[j].y || shu[i].x > heng[j].x)
                        continue;
                    X = heng[j].x;
                    Y = shu[i].y;
                    int temp1 = X - shu[i].x;
                    int temp2 = m - Y + 2;
                    add(pos[i][temp1],pos[j + cnt1][temp2],1000);
                }
                if (shu[i].opt == -2 && heng[j].opt == -3) //下左
                {
                    if (shu[i].x > heng[j].x || shu[i].y > heng[j].y)
                        continue;
                    X = heng[j].x;
                    Y = shu[i].y;
                    int temp1 = X - shu[i].x;
                    int temp2 = Y + 1;
                    add(pos[i][temp1],pos[j + cnt1][temp2],1000);
                }
            }
        dinic();
        printf("%d
    ",ans);
    
        return 0;
    }
  • 相关阅读:
    VC 常见问题百问
    python windows 环境变量
    Check server headers and verify HTTP Status Codes
    Where are the AES 256bit cipher suites? Please someone help
    outlook 如何预订会议和会议室
    安装Axis2的eclipse插件后,未出现界面
    windows 环境变量
    python 时间日期处理汇集
    openldap学习笔记(使用openldap2.3.32)
    set p4 environment in windows
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8709536.html
Copyright © 2020-2023  润新知