题目链接

题目大意

一个n*m的网格上有一些点,一个点可以跳到与其同一行或同一列的点上。给定起点和终点。

求要使起点不能跳到终点,最少撤走几个点。

\(n,m\leq 100\)

解题思路

考虑将能够互相到达的点之间连边,题目要求即使删去尽可能少的点使图不连通。

十分套路地把一个点拆成一个入点和出点,之间连一条流量为1的边,删去这个点即使割去这条边。

然后就是网络流板子了。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cstring>
#define N 40010
#define M N*100
#define N1 110
#define ll long long
#define inf 1000000000
using namespace std;
struct node{
int nxt,to;
ll f;
}road[M];
int head[N],cur[N],cnt=1;
void add(int u,int v,ll f)
{
road[++cnt]=(node){head[u],v,f};
head[u]=cnt;
road[++cnt]=(node){head[v],u,0};
head[v]=cnt;
}
queue<int>q;
int dep[N];
bool bfs(int s,int t)
{
memcpy(cur,head,sizeof(cur));
memset(dep,127,sizeof(dep));
dep[s]=0;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=road[i].nxt)
if(road[i].f>0)
{
int v=road[i].to;
if(dep[v]>=inf)
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return dep[t]<=inf;
}
ll dfs(int u,int t,ll flow)
{
if(u==t || !flow) return flow;
ll ans=0;
for(int i=cur[u];i;i=road[i].nxt)
{
cur[u]=i;
int v=road[i].to,f=0;
if(dep[v]==dep[u]+1 && (f=dfs(v,t,min(flow,road[i].f))))
{
flow-=f;
ans+=f;
road[i].f-=f;
road[i^1].f+=f;
if(!flow) break;
}
}
return ans;
}
ll dinic(int s,int t)
{
ll ans=0;
while(bfs(s,t)) ans+=dfs(s,t,inf);
return ans;
}
int n,m;
int id(int x,int y){return (x-1)*m+y;}
int ids(int x,int o){return x*2+o;}
void add_e(int x,int y)
{
add(ids(x,1),ids(y,0),inf);
add(ids(y,1),ids(x,0),inf);
}
char str[N1][N1];
int main()
{
scanf("%d%d",&n,&m);
int s=(n*m)*2+2,t=s+1;
for(int i=1;i<=n;i++) scanf("%s",str[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(str[i][j]!='.')
{
for(int k=i+1;k<=n;k++)
if(str[k][j]!='.')
add_e(id(i,j),id(k,j));
for(int k=j+1;k<=m;k++)
if(str[i][k]!='.')
add_e(id(i,j),id(i,k));
if(str[i][j]=='S')
add(s,ids(id(i,j),0),inf),add(ids(id(i,j),0),ids(id(i,j),1),inf);
else if(str[i][j]=='T')
add(ids(id(i,j),1),t,inf),add(ids(id(i,j),0),ids(id(i,j),1),inf);
else add(ids(id(i,j),0),ids(id(i,j),1),1);
}
ll ans=dinic(s,t);
printf("%lld\n",ans>=inf?-1:ans);
return 0;
}

agc026F Lotus Leaves的更多相关文章

  1. AtCoder - 2568 Lotus Leaves

    Problem Statement There is a pond with a rectangular shape. The pond is divided into a grid with H r ...

  2. 【ARC074F】Lotus Leaves 最小割

    Description 给你一个n*m网格图,有起点荷叶和终点荷叶,有中转荷叶,其他的格子没东西,一个荷叶可以跳到同一行或者列的另一个荷叶.问最多删掉几个中转荷叶能让起点终点不连通.如果不行输出-1. ...

  3. AtCoder Regular Contest 074F - Lotus Leaves

    $n \leq 300,m \leq 300$,$n*m$的格子里有起点有终点有空地有障碍,人会从起点选一个同行或同列空地跳过去,然后一直这样跳到终点.求至少删掉多少格子使得人跳不到终点. 首先S和T ...

  4. AtCoder Regular Contest 074 F - Lotus Leaves

    题目传送门:https://arc074.contest.atcoder.jp/tasks/arc074_d 题目大意: 给定一个\(H×W\)的网格图,o是可以踩踏的点,.是不可踩踏的点. 现有一人 ...

  5. 【arc077f】AtCoder Regular Contest 074 F - Lotus Leaves

    题意 给定一个n*m的池塘,每个格子上可能有叶子. 从一个叶子出发,可以跳到相同行或相同列的叶子. 问至少去掉多少叶子,使得起点不能到达终点. \(n,m<=100\) 解法 很显然的最小割模型 ...

  6. 【AtCoder】ARC074

    ARC 074 C - Chocolate Bar 直接枚举第一刀横切竖切,然后另一块要求如果横切分成\(H / 2\)竖切分成\(W/2\)即可 #include <bits/stdc++.h ...

  7. Atcoder Regular-074 Writeup

    C - Chocolate Bar 题面 There is a bar of chocolate with a height of H blocks and a width of W blocks. ...

  8. 2017年上海金马五校程序设计竞赛:Problem I : Frog's Jumping (找规律)

    Description There are n lotus leaves floating like a ring on the lake, which are numbered 0, 1, ..., ...

  9. AtCoder刷题记录

    构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...

随机推荐

  1. SuperSocket与SuperSocket.ClientEngine实现Protobuf协议

    参考资料说明 SuperSocket文档 http://docs.supersocket.net/ Protobuf语言参考 https://developers.google.com/protoco ...

  2. 二分题 D - Salary Changing codeforce

    题意:给出n个人(n是奇数),s钱:s为总的可以付工钱的钱: 每一个工人有一个付工钱的区间,只要在这个区间范围内,随便一个数都可以当作给这个工人付了钱: 老板要付给每个工人钱,并且付钱的中位数要尽可能 ...

  3. day11 ss命令 查看网络端口使用情况及对应pid centos7

    [root@oldboyedu ~]# ss -lntup Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port udp UNC ...

  4. Apache Kafka(十)Partitions与Replication Factor 调整准则

    Partitions与Replication Factor调整准则 Partition 数目与Replication Factor是在创建一个topic时非常重要的两个参数,这两个参数的取值会直接影响 ...

  5. python的setup和teardown

    关于python unittest ① setup():每个测试函数运行前运行② teardown():每个测试函数运行完后执行③ setUpClass():必须使用@classmethod 装饰器, ...

  6. Linux中 /boot 目录介绍

    转自https://blog.csdn.net/dulin201004/article/details/7396968 一./boot/目录中的文件和目录 Linux系统在本地启动时,目录/boot/ ...

  7. 剑指offer 面试题38 字符串的排列

    我惯用的dfs模板直接拿来套 class Solution { public: vector<string> Permutation(string str) { if(str.empty( ...

  8. 抽象工厂模式(JAVA反射)

    实例代码(JAVA):模式动机     在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方 ...

  9. 7_1 除法(UVa725)<选择合适的枚举对象>

    如果把数字0到9分配成2个整数(各五位数),现在请你写一支程序找出所有的配对使得第一个数可以整除第二个数,而且商为N(2<=N<=79),也就是:abcde / fghijk = N这里每 ...

  10. 计算几何-点与多边形的位置判断-zoj1081Points Within

    This article is made by Jason-Cow.Welcome to reprint.But please post the writer's address. http://ww ...