AtCoder Regular Contest 074F - Lotus Leaves
$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的更多相关文章
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
- AtCoder Regular Contest 096
AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...
- AtCoder Regular Contest 097
AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...
随机推荐
- CSAPP lab1 datalab-handout
这是一个关于机器级的整数.浮点数表示和位运算的实验.要求用给定的操作符.尽可能少的操作数去实现对应的函数功能. 完整的实验包:链接: https://pan.baidu.com/s/1xUBi3XDl ...
- 优先队列的使用——Expedition
一.题目描述 你需要驾驶一辆卡车行驶L单位距离.最开始时,卡车上有P单位的汽油.卡车每开1单位距离需要消耗1单位的汽油.如果在途中车上的汽油耗尽,卡车就无法继续前行,因而无法到达终点.中途共有N个加油 ...
- 背包问题2 (lintcode)
这里: for(int j = 1;j <= m;j++) result[0][j] = 0x80000000; 不能从0开始,result[0][0]是可以取到的,是0.其他情况取不到才用最小 ...
- Fisherfaces 算法的具体实现源码
/* * Copyright (c) 2011. Philipp Wagner <bytefish[at]gmx[dot]de>. * Released to public domain ...
- Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币
什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...
- HTML5 Canvas奇幻色彩Loading加载动画
转自 https://www.html5tricks.com/tag/loading%E5%8A%A8%E7%94%BB/
- 【状态压缩 meet in middle】poj3139Balancing the Scale
数组溢出真是可怕的事情 Description You are given a strange scale (see the figure below), and you are wondering ...
- MySQLfailover错误一则
由于公司现有主库要转移到新的主库上,所以,我打算利用MySQLfailover工具的故障转移. 1.开发把程序账号转移到新主库上 2.停止现有主库,使之进行故障转移,转移期间会自动锁表,保持数据一致性 ...
- python-格式化输出(考试必考)
Python与用户交互 如何交互 我们使用input()方法来与用户交互,但是无论我们输入的值是数字类型.字符串类型.列表类型,input的接收值都是字符串类型. name = input('请输入你 ...
- nw335 debian sid x86-64 -- 2 驱动的方式
1 linux内核自带 2 realtek 提供的官方驱动 3 使用xp的驱动 4 第三方驱动(现在成功的,最好的方式)