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

首先S和T同行或同列无解。

这不是裸的最小割嘛。。等会这复杂度不大对

优化:一行里的点要连来连去嘛,每个点都要向同行或同列的所有点连inf边嘛,那咱把这边聚一下,每行每列新开一个点,这一行的所有点连向代表这一行的点,代表这一行的点连向所有这一行的点,这样边从三次方变成了平方。可过。

还有一种建图方法:每行每列开一个点,把一个空地对应的行列连条边,起点向其行列连边,终点其行列向终点连边。

 //#include<iostream>
#include<cstring>
#include<cstdio>
//#include<time.h>
//#include<complex>
//#include<queue>
#include<algorithm>
#include<stdlib.h>
using namespace std; #define LL long long
int qread()
{
char c; int s=; while ((c=getchar())<'' || c>'');
do s=s*+c-''; while ((c=getchar())>='' && c<=''); return s;
} //Pay attention to '-' and LL of qread!!!! int n,m;
#define maxn 400011
#define maxm 4000011
struct Edge{int to,next,cap,flow;};
struct Network
{
Edge edge[maxm]; int first[maxn],le,n;
void clear(int m) {le=; n=m;}
void in(int x,int y,int cap)
{Edge &e=edge[le]; e.to=y; e.cap=cap; e.flow=; e.next=first[x]; first[x]=le++;}
void insert(int x,int y,int cap) {in(x,y,cap); in(y,x,);}
int s,t,dis[maxn],cur[maxn],que[maxn],head,tail;
bool bfs()
{
memset(dis,,sizeof(dis)); dis[s]=;
head=; tail=; que[]=s;
while (head!=tail)
{
int now=que[head++];
for (int i=first[now];i;i=edge[i].next)
{
Edge &e=edge[i];
if (e.cap>e.flow && dis[e.to]==)
{
dis[e.to]=dis[now]+;
que[tail++]=e.to;
}
}
}
return dis[t];
}
int dfs(int x,int a)
{
if (x==t || !a) return a;
int flow=,f;
for (int &i=cur[x];i;i=edge[i].next)
{
Edge &e=edge[i];
if (dis[e.to]==dis[x]+ && (f=dfs(e.to,min(a,e.cap-e.flow)))>)
{
e.flow+=f; flow+=f;
edge[i^].flow-=f; a-=f;
if (!a) break;
}
}
return flow;
}
int Dinic(int s,int t)
{
this->s=s; this->t=t;
int ans=;
while (bfs())
{
for (int i=;i<=n;i++) cur[i]=first[i];
ans+=dfs(s,0x3f3f3f3f);
}
return ans;
}
}g; char mp[][]; int id[][]; int main()
{
// freopen("trade.in","r",stdin);
// freopen("trade.out","w",stdout);
n=qread(); m=qread();
for (int i=;i<=n;i++) scanf("%s",mp[i]+);
int sx,sy,tx,ty,s,t,tot=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++) if (mp[i][j]!='.')
{
id[i][j]=++tot;
if (mp[i][j]=='S') sx=i,sy=j,s=tot;
if (mp[i][j]=='T') tx=i,ty=j,t=tot;
} if (sx==tx || sy==ty) {puts("-1"); return ;} g.clear(tot*+n+m);
for (int i=;i<=tot;i++) if (i!=s && i!=t) g.insert(i,i+tot,);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++) if (id[i][j])
{
if (id[i][j]==s)
{
g.insert(s,tot*+i,0x3f3f3f3f);
g.insert(tot*+i,s,0x3f3f3f3f);
g.insert(s,tot*+n+j,0x3f3f3f3f);
g.insert(tot*+n+j,s,0x3f3f3f3f);
}
else
{
g.insert(id[i][j]+tot,tot*+i,0x3f3f3f3f);
g.insert(tot*+i,id[i][j],0x3f3f3f3f);
g.insert(id[i][j]+tot,tot*+n+j,0x3f3f3f3f);
g.insert(tot*+n+j,id[i][j],0x3f3f3f3f);
}
}
printf("%d\n",g.Dinic(s,t));
return ;
}

AtCoder Regular Contest 074F - Lotus Leaves的更多相关文章

  1. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  2. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  3. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  4. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  5. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

  6. AtCoder Regular Contest 095

    AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...

  7. AtCoder Regular Contest 102

    AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...

  8. AtCoder Regular Contest 096

    AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...

  9. AtCoder Regular Contest 097

    AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...

随机推荐

  1. UVa 12219 Common Subexpression Elimination (stl,模拟,实现)

    一般来说,把一颗子树离散成一个int,把一个结点的字符离散成一个int会方便处理 直接map离散.当然一个结点最多只有4个小写字母,也可以直接编码成一个27进制的整数,舍掉0,为了区分0和0000. ...

  2. CPP-基础:char、BYTE、byte

    一,C++语言的内建类型中没“BYTE”这么个类型.BYTE是WINDOWS Platform SDK中windef.h里面定义的:typedef unsigned char BYTE; 二,char ...

  3. Java中集合类

    一.Collection Collection 接口用于表示任何对象或元素组.想要尽可能以常规方式处理一组元素时,就使用这一接口.Collection 在前面的大图也可以看出,它是List 和 Set ...

  4. bootstrap 两端对齐的导航

    您可以在屏幕宽度大于768px时,通过在分别使用.nav .nav-tabs或.nav .nav-pills的同时使用class.nav-justified,让标签式或胶囊式导航菜单与父元素等宽,在更 ...

  5. Django ORM (一) 创建数据库和模型常用的字段类型参数及Field 重要参数介绍

    创建一个 Django 项目及应用 django-admin startproject orm cd orm python manage.py startapp app01 在 models.py 上 ...

  6. wordpress配置SMTP服务发送邮件(qq邮箱)

    wordpress有一个注册功能,填了用户名和邮箱后,会收到一封邮件,邮件里有一个链接,点击该链接可以获得密码和修改密码.但是,最开始,你会发现,等半天都没有收到邮件,再等到猴年马月也不会收到. 但是 ...

  7. [转]automaticallyAdjustsScrollViewInsets(个人认为iOS7中略坑爹的属性)

    @当我们在一个UIViewController中同时创建2个tableView的时候,如果把它们的frame中的Y坐标设置为一样,你可能会发现它们的位置并没有达到你想要的结果.比如第一tableVie ...

  8. 解决like '%字符串%'时索引不被使用的方法

    解决like '%字符串%'时索引不被使用的方法   分步阅读 解决like '%字符串%'时索引不被使用的方法,如果like以通配符开头('%abc')时索引会失效会变成全表扫描的操作. 工具/原料 ...

  9. Myeclipse 添加Android开发工具

    1.JDK是必须的,同时配置相应环境变量. 2.Android SDK 下载后解压缩需要把SDK目录下的tools和platform-tools加入环境变量. 3.MyEclipse中安装ADT插件 ...

  10. 【Linux】网卡配置与绑定

    Redhat Linux的网络配置,基本上是通过修改几个配置文件来实现的. 虽然也可以用ifconfig来设置IP,用route来配置默认网关,用hostname来配置主机名,但是重启后会丢失. 相关 ...