$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. mongo ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused

    解决方法 rm /var/lib/mongodb/mongod.lock

  2. Go 1.4 正式版发布,官方正式支持 Android

    Go 1.4 正式发布啦,是第五个 Go 的稳定版本,与上一个稳定版本 Go 1.3 相隔 6 个月.Go 1.4 包括一些小的语言改进,支持更多的操作系统和处理器架构:改进了工具链和库.同时,Go ...

  3. couldn't be opened because you don't have permission to view it” 解决方法

    I use Xcode6 GM. I encountered the same problem. What I did was to go to Build Options. Then I chang ...

  4. OC 导入类 #import和@class 区别

    objective-c中#import和@class的区别 在Objective-C中,可以使用#import和@class来引用别的类型, 但是你知道两者有什么区别吗? @class叫做forwar ...

  5. redis分布式共享锁模拟抢单的实现

    本篇内容主要讲解的是redis分布式锁,并结合模拟抢单的场景来使用,内容节点如下: jedis的nx生成锁 如何删除锁 模拟抢单动作 1.jedis的nx生成锁 对于分布式锁的生成通常需要注意如下几个 ...

  6. Codeforces Round #277.5 (Div. 2)-B. BerSU Ball

    http://codeforces.com/problemset/problem/489/B B. BerSU Ball time limit per test 1 second memory lim ...

  7. 二分查找算法java

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元 ...

  8. shell脚本,如何监控目录下的文件内容是否被修改。

    第一种方法是通过cmp来进行比对[root@localhost bo]# ls .html .html .html .html .html .html .html .html .html cat.sh ...

  9. vue组件从开发到发布

    组件化是前端开发非常重要的一部分,从业务中解耦出来,可以提高项目的代码复用率.更重要的是我们还可以打包发布,俗话说集体的力量是伟大的,正因为有许许多多的开源贡献者,才有了现在的世界. 不想造轮子的工程 ...

  10. 小数据池 is 和 ==的区别

    小数据池 一.小数据池 1)代码块 python程序是由代码块构成的,一个代码块的文本作为pythont程序执行的单元 官方文档: A Python program is constructed fr ...