标签:turn scan str color fclose print clu 匈牙利 dfs
题目大意:给出n*m的矩阵以及r,c。求最小路径覆盖。
本来是匈牙利算法裸题,网络流也可以跑一跑。
但是我先粘一个骗分大错解:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,r,c,a[55],ans; char mp[55][55]; int use[55][55],cov[55][55]; int main() { // freopen("legion.in","r",stdin); // freopen("legion.out","w",stdout); scanf("%d%d%d%d",&n,&m,&r,&c); for(int i=1;i<=n;i++) { scanf("%s",mp[i]+1); for(int j=1;j<=m;j++) { a[i]+=(mp[i][j]==‘.‘); if(mp[i][j]==‘x‘)use[i][j]=1; } ans+=a[i]; } for(int i=1;i<=n;i++) { if(i>r) { for(int j=1;j<=m;j++) { if(mp[i][j]==‘x‘)continue; if(j>c&&use[i-r][j-c]==0) { use[i-r][j-c]=1; cov[i][j]=1; ans--; }else if(j+c<=m&&use[i-r][j+c]==0) { use[i-r][j+c]=1; cov[i][j]=1; ans--; } } } if(r!=c&&i>c) { for(int j=1;j<=m;j++) { if(cov[i][j])continue; if(mp[i][j]==‘x‘)continue; if(j>r&&use[i-c][j-r]==0) { use[i-c][j-r]=1; cov[i][j]=1; ans--; }else if(j+r<=m&&use[i-c][j+r]==0) { use[i-c][j+r]=1; cov[i][j]=1; ans--; } } } } printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0; }
这是我考试时写的(因为没好好听匈牙利算法和网络流),但是无脑骗了60?
放到某谷上面测70?
恕我直言在座的数据都很强
接下来是整解:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 55 int n,m,r,c,hed[N*N],cnt; char mp[N][N]; struct EG { int to,nxt; }e[4*N*N]; void ae(int f,int t) { e[++cnt].to = t; e[cnt].nxt = hed[f]; hed[f] = cnt; } int tn(int x,int y){return (x-1)*m+y;} int dx[4],dy[4],fa[N*N]; bool vis[N*N]; int dfs(int x)//Hungary { vis[x]=1; for(int j=hed[x];j;j=e[j].nxt) { int to = e[j].to; if(!vis[to]) { vis[to]=1; if(!fa[to]||dfs(fa[to])) { fa[to]=x; return 1; } } } return 0; } int main() { // freopen("legion.in","r",stdin); // freopen("legion.out","w",stdout); scanf("%d%d%d%d",&n,&m,&r,&c); dx[0]=dx[1]=dy[2]=r,dx[2]=dx[3]=dy[0]=c,dy[1]=-c,dy[3]=-r; for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(mp[i][j]==‘.‘) { for(int k=0;k<4;k++) { int x = i+dx[k],y = j+dy[k]; if(x<=0||y<=0||x>n||y>m)continue; if(mp[x][y]==‘.‘) ae(tn(i,j),tn(x,y)); } } } } int ans =0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(mp[i][j]==‘.‘) { memset(vis,0,sizeof(vis)); ans+=(dfs(tn(i,j))==0); } } } printf("%d\n",ans); return 0; }
标签:turn scan str color fclose print clu 匈牙利 dfs
原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9743715.html