# 省选模拟赛 cti

3 cti (cti.cpp/in/out, 1s, 512MB)
3.1 Description

3.2 Input Format

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

需要注意的是炮塔可以不攻击任何敌人，那么连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;

w[tot] = 0;
to[tot] = x;
}

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
if (j == 1)
}
}
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
if (j == 1)
}
}
}
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
if (j == 1)
}
}
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
if (j == 1)
}
}
}
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;
}
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;
}
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;
}
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;
}