题目
Description
在美鱼和理树后援团拯救世界的同时,外表柔弱的理树也开始坚强起来,思考着离开这个世界的办法。误打误撞地,她遇上了正在教室破坏课桌打开迷宫入口的沙耶。沙耶告诉理树,这个世界的出口就是这个迷宫的出口。于是理树毫不犹豫地跟沙耶一起跳进了迷宫。在迷宫里,两个女孩子互帮互助,一会儿割绳子,一会儿泡温泉,一会儿雕冰块,跌跌撞撞地走到了终点。不出所料,终点也有一个机关在等着她们。
终点的机关是一个立着的m*n 的方格棋盘,在有些格子上放了一个玩偶,而有些地方直接挖了个大坑。只有取走所有玩偶才能打开出口。但是,由于奇怪的设定,理树和沙耶不能直接触碰玩偶,他们需要操纵机器人来收集它。机器人的走法很奇怪,和国际象棋的马有点像,只不过马可以走任意方向的1*2 路线,它们只会由上往下走r*c(或c*r)的路线,不能回头。而机器人一旦经过一个有玩偶的格子,那个格子上的玩偶将被回收,并且在机器人离开时,那个格子会变成一个坑。理树可以把机器人放在任何一个有玩偶的格子上作为起点,也可以在任何一个有玩偶的格子回收机器人。机器人行走可以视为瞬移,只不过每一次设置新起点都会消耗1 时间。并且,有坑的格子不能落脚。
就在这个紧要关头,玩偶狂热爱好者的沙耶却流着口水智商归0。理树不得不转而求助你,帮忙计算出最少多少时间就能收集到所有玩偶。
终点的机关是一个立着的m*n 的方格棋盘,在有些格子上放了一个玩偶,而有些地方直接挖了个大坑。只有取走所有玩偶才能打开出口。但是,由于奇怪的设定,理树和沙耶不能直接触碰玩偶,他们需要操纵机器人来收集它。机器人的走法很奇怪,和国际象棋的马有点像,只不过马可以走任意方向的1*2 路线,它们只会由上往下走r*c(或c*r)的路线,不能回头。而机器人一旦经过一个有玩偶的格子,那个格子上的玩偶将被回收,并且在机器人离开时,那个格子会变成一个坑。理树可以把机器人放在任何一个有玩偶的格子上作为起点,也可以在任何一个有玩偶的格子回收机器人。机器人行走可以视为瞬移,只不过每一次设置新起点都会消耗1 时间。并且,有坑的格子不能落脚。
就在这个紧要关头,玩偶狂热爱好者的沙耶却流着口水智商归0。理树不得不转而求助你,帮忙计算出最少多少时间就能收集到所有玩偶。
Input
第一行包含4 个整数M、N、R、C,意义见问题描述。接下来M 行每行一个长度为N 的
字符串。如果某个字符是'.',表示这个地方有一个玩偶;如果这个字符是'x',表示这个地
方是坑。
字符串。如果某个字符是'.',表示这个地方有一个玩偶;如果这个字符是'x',表示这个地
方是坑。
Output
输出一个整数,表示最短时间。
Sample Input
3 3 1 2
...
.x.
...
Sample Output
4
Data Constraint
30%的数据中,1<=M,N<=4,1<=R,C<=3。
70%的数据中,1<=M<=20,1<=N<=4,1<=R,C<=3。
100%的数据中,1<=M,N<=50,1<=R,C<=10。
70%的数据中,1<=M<=20,1<=N<=4,1<=R,C<=3。
100%的数据中,1<=M,N<=50,1<=R,C<=10。
Hint
![](https://img-blog.csdnimg.cn/2022010615491877007.png)
分析
- 首先标点,然后跑二分图
- 答案=空格数-最大匹配
代码
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<vector> 5 using namespace std; 6 long long n,m,x,y,ans,link[100001],s[205][205],p,ss; 7 vector<int> f[10001]; 8 bool cover[100001]; 9 int map[100][100],rk[100][100]; 10 bool find(int i) 11 { 12 for (int k=0;k<f[i].size();k++) 13 if (!cover[f[i][k]]) 14 { 15 int j=f[i][k]; 16 cover[j]=true; 17 int q=link[j]; 18 link[j]=i; 19 if (q==0||find(q)) return true; 20 link[j]=q; 21 } 22 return false; 23 } 24 int main() 25 { 26 int n,m,r,c; 27 cin>>n>>m>>r>>c; 28 char num; 29 int fx[4][2]={{r,c},{c,r},{r,-c},{c,-r}}; 30 int cnt=0,tot=0; 31 for (int i=1;i<=n;i++) 32 for (int j=1;j<=m;j++) 33 { 34 cin>>num; 35 if (num=='.') map[i][j]=1,rk[i][j]=++cnt; 36 else tot++; 37 } 38 for (int i=1;i<=n;i++) 39 for (int j=1;j<=m;j++) 40 for (int k=0;k<4;k++) 41 { 42 int ax=i+fx[k][0],ay=j+fx[k][1]; 43 if (ax>n||ay>m||ax<1||ay<1||!map[ax][ay]) continue; 44 f[rk[i][j]].push_back(rk[ax][ay]); 45 } 46 int ans=0; 47 for (int i=1;i<=n;i++) 48 { 49 for (int j=1;j<=m;j++) 50 { 51 if (map[i][j]==1) 52 { 53 memset(cover,0,sizeof(cover)); 54 ans+=find(rk[i][j]); 55 } 56 } 57 } 58 cout<<n*m-tot-ans; 59 }