#include <bits/stdc++.h>
using namespace std;
const int MX=100100,ME=42*MX,INF=1000100100;
int n,m,S,T,e,z,cnt[MX],q[MX],dst[MX],ptr[MX],t[ME],c[ME],f[ME];
vector<int> g[MX];
char s[20][MX];
int dfs(int i, int cur) {
if (i==T) return cur;
for (; ptr[i]<g[i].size(); ++ptr[i]) {
int ed=g[i][ptr[i]],k=t[ed];
//printf(" try dfs %d->%d (%d bool=%d cap=%d)\n",i,k,ed,dst[k]==dst[i]+1,cur);
if (dst[k]==dst[i]+1) {
int fl=min(cur,c[ed]-f[ed]);
if (fl>0) fl=dfs(k,fl);
if (fl>0) {
//printf(" dfs %d->%d (%d) -=%d\n",i,k,ed,fl);
f[ed]+=fl;
f[ed^1]-=fl;
return fl;
}
}
}
return 0;
}
bool pe() {
for (int i=0; i<=T; i++) dst[i]=INF;
dst[S]=0;
q[0]=S;
for (int fi=0, fr=1; fi<fr; ) {
int i=q[fi++];
for (int ed: g[i]) if (f[ed]<c[ed]) {
int y=t[ed];
//printf("%d -%d-> %d (%d %d)\n",i,ed,y,f[ed],c[ed]);
if (dst[y]>dst[i]+1) {
dst[y]=dst[i]+1;
q[fr++]=y;
}
}
}
return dst[T]<INF;
}
void add_edge(int fr, int to, int v) {
t[e]=to; c[e]=v; f[e]=0; g[fr].push_back(e++);
t[e]=fr; c[e]=0; f[e]=0; g[to].push_back(e++);
}
int main() {
scanf("%d%d",&n,&m);
S=n+m; T=S+1;
for (int i=0; i<n; i++) {
scanf("%s",s[i]);
add_edge(S,i,1);
}
for (int i=0; i<n; i++) for (int j=0; j<m; j++) if (s[i][j]=='.') {
++cnt[j];
add_edge(i,n+j,n);
}
int le=0,ri=0;
for (int j=0; j<m; j++) if (cnt[j]>0) {
add_edge(n+j,T,(cnt[j]-1)*n);
ri+=cnt[j]-1;
} else { puts("-1"); return 0; }
while (le<ri) {
int mid=(le+ri)/2+1;
//printf("mid=%d\n",mid);
for (int i=0; i<e; i++) f[i]=0;
for (int i=0; i<n; i++) c[i*2]=mid;
int tot=0;
while (pe()) {
for (int i=0; i<=T; i++) ptr[i]=0;
for (; z=dfs(S,INF); tot+=z);// printf("z=%d\n",z);
}
if (tot==mid*n) le=mid; else ri=mid-1;
}
int g=__gcd(ri,n);
printf("%d/%d\n",ri/g,n/g);
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #include <bits/stdc++.h> using namespace std; const int MX=100100,ME=42*MX,INF=1000100100; int n,m,S,T,e,z,cnt[MX],q[MX],dst[MX],ptr[MX],t[ME],c[ME],f[ME]; vector<int> g[MX]; char s[20][MX]; int dfs(int i, int cur) { if (i==T) return cur; for (; ptr[i]<g[i].size(); ++ptr[i]) { int ed=g[i][ptr[i]],k=t[ed]; //printf(" try dfs %d->%d (%d bool=%d cap=%d)\n",i,k,ed,dst[k]==dst[i]+1,cur); if (dst[k]==dst[i]+1) { int fl=min(cur,c[ed]-f[ed]); if (fl>0) fl=dfs(k,fl); if (fl>0) { //printf(" dfs %d->%d (%d) -=%d\n",i,k,ed,fl); f[ed]+=fl; f[ed^1]-=fl; return fl; } } } return 0; } bool pe() { for (int i=0; i<=T; i++) dst[i]=INF; dst[S]=0; q[0]=S; for (int fi=0, fr=1; fi<fr; ) { int i=q[fi++]; for (int ed: g[i]) if (f[ed]<c[ed]) { int y=t[ed]; //printf("%d -%d-> %d (%d %d)\n",i,ed,y,f[ed],c[ed]); if (dst[y]>dst[i]+1) { dst[y]=dst[i]+1; q[fr++]=y; } } } return dst[T]<INF; } void add_edge(int fr, int to, int v) { t[e]=to; c[e]=v; f[e]=0; g[fr].push_back(e++); t[e]=fr; c[e]=0; f[e]=0; g[to].push_back(e++); } int main() { scanf("%d%d",&n,&m); S=n+m; T=S+1; for (int i=0; i<n; i++) { scanf("%s",s[i]); add_edge(S,i,1); } for (int i=0; i<n; i++) for (int j=0; j<m; j++) if (s[i][j]=='.') { ++cnt[j]; add_edge(i,n+j,n); } int le=0,ri=0; for (int j=0; j<m; j++) if (cnt[j]>0) { add_edge(n+j,T,(cnt[j]-1)*n); ri+=cnt[j]-1; } else { puts("-1"); return 0; } while (le<ri) { int mid=(le+ri)/2+1; //printf("mid=%d\n",mid); for (int i=0; i<e; i++) f[i]=0; for (int i=0; i<n; i++) c[i*2]=mid; int tot=0; while (pe()) { for (int i=0; i<=T; i++) ptr[i]=0; for (; z=dfs(S,INF); tot+=z);// printf("z=%d\n",z); } if (tot==mid*n) le=mid; else ri=mid-1; } int g=__gcd(ri,n); printf("%d/%d\n",ri/g,n/g); return 0; } |
English