题目链接

题目大意

一个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;
}

最新文章

  1. Ubuntu1404 (2)
  2. redis常用命令小结
  3. Twitter Storm中Bolt消息传递路径之源码解读
  4. Samba服务器安装及配置
  5. Ubuntu中NetBeans C/C++配置、编译
  6. SetUID、SetGID中的大小写Ss和Sticky bit中的大小写Tt
  7. 【Java】java基本知识
  8. POPTEST培训:web自动化测试之DOM
  9. How to enable your website to public(set up your web server at home)
  10. Java-IO之FileReader和FileWriter
  11. Java(16)接口
  12. angular2 图片赋值的时候前面自动加 unsafe:xxx 导致图片信息不显示问题
  13. rhel配置网络yum源
  14. python练习--利用while循环和if语句,完成猜骰子的数字大小
  15. 使用DatagramSocket和DatagramPacket进行简单的通信
  16. PAT之写出这个数
  17. Kotlin入门(24)如何自定义视图
  18. February 11th, 2018 Week 7th Sunday
  19. Win10系列:C#应用控件基础14
  20. Intel支持八九代酷睿的B365芯片组将登场亮相

热门文章

  1. HTTP状态码的浪漫故事
  2. 什么是文件的BOM头,及BOM头有哪些坑?
  3. dremio的学习点滴
  4. IntelliJ IDEA之如何设置JVM运行参数
  5. go语言 二叉树
  6. python如何将自己写的代码打包供他人使用
  7. angular清空node_modules
  8. kill pkill
  9. AcWing 849. Dijkstra求最短路 I 朴素 邻接矩阵 稠密图
  10. Homebrew安装和Mac使用