今や上限と下限と最小カットネットワークフローモデル(最大重量サブグラフが閉じている)に加えて、それは使用しないクラスの正しさを証明しません。より多くの熟練の残りの部分。
良い質問は、これは問題の解決策の対象で無駄を見に長い時間のようないくつかの感触の私の選択です。
私たちの周り尋ねた質問には、隣接する部分を交換することができ、また、最終的な交換で最終状態の数を制限します。
1.黒と白の二枚の状態が片の数を制御しない場合は-1でなければなりません
2.この質問はハーフだと思うが、それは私たちのトラフィックとの一切の関係にのみ明らかにこのアイデアは答えへの回答と私たちのプロセスと少し接触を持って廃棄されていない、この二分法は無用の最小数を見つけることは難しいことではありません。
3.その後、最小のコストは明らかに我々は最大流量の最終コストのコストが答えである最小限にしたいの交換の費用流で求めることができるよう。
この場合には交換されず、格子の交換に関与する個数が制限されること4.注意。
2枚は明らかに交換されている私達はちょうど私たちは気にしない行って作品をスワップアウトされているのではなく、出て作品の交換を追求する必要があります。これは焦点である、我々は我々だけ行くとそれが交換されますが、直接ご無視する場所を気にソースポイントから始まるフローのためにこの事を考えなければなりません。
無用個でなければならないので、交換される同じ色は、次に交換は無意味であろう場合に交換される部品の数は、異なる色でなければならないことを考えると、それはまた、回答を増大はありません。
6.私たちは、交換はまだ二つの点に分割する点のみである場合にスワップアウトされ、その後、我々はこのケースを区別することができないかわかりません。
それはスワップアウト切り替えを占めストリームではないので、3に7分割は点光源から来ます。
8.問題はポイント数に分割し、より頻繁に着信1点より一定の回数を指摘されていない場合は、ポイントではない点よりも出てきて、それを二等分する点は何もそれを二分していません。
ランニングコストの9さえコストが流れることができます。
しかし、一般的に、そのような正しいコードを少し変更されているされているが、あまりにも、それは神が本当に彼に感謝2H見て私を助ける石のピットを滞在することができ、なぜ70分後、私は知りません。
//#include<bits/stdc++.h> #include<iomanip> #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<queue> #include<deque> #include<cmath> #include<ctime> #include<cstdlib> #include<stack> #include<algorithm> #include<vector> #include<cctype> #include<utility> #include<set> #include<bitset> #include<map> #define INF 1000000000 #define ll long long #define min(x,y) (x>y?y:x) #define max(x,y) (x>y?x:y) #define RI register ll #define up(p,i,n) for(ll i=p;i<=n;++i) #define db double using namespace std; char buf[1<<15],*fs,*ft; inline char getc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int MAXN=25,maxn=MAXN*MAXN*MAXN*MAXN; int n,m,S,T,cnt,sum,sum1,flag,len=1,t,h,maxflow,ans; char c[MAXN][MAXN]; int a[MAXN][MAXN],pos[MAXN][MAXN],b[MAXN][MAXN]; int lin[maxn],nex[maxn],ver[maxn],e[maxn],e1[maxn]; int pre[maxn],in[maxn],vis[maxn],q[maxn],dis[maxn]; const int dx[9]={0,1,1,1,0,0,-1,-1,-1}; const int dy[9]={0,0,-1,1,1,-1,0,-1,1}; inline void add(int x,int y,int z,int z1) { ver[++len]=y;nex[len]=lin[x];lin[x]=len;e[len]=z;e1[len]=z1; ver[++len]=x;nex[len]=lin[y];lin[y]=len;e[len]=0;e1[len]=-z1; } inline int spfa() { for(int i=1;i<=T;++i)dis[i]=INF; t=h=0;q[++t]=S;vis[S]=1;dis[S]=0;in[S]=INF; while(h++<t) { int x=q[h];vis[x]=0; for(int i=lin[x];i;i=nex[i]) { int tn=ver[i]; if(!e[i])continue; if(dis[tn]>dis[x]+e1[i]) { dis[tn]=dis[x]+e1[i]; in[tn]=min(in[x],e[i]); pre[tn]=i; if(!vis[tn])q[++t]=tn,vis[tn]=1; } } } return dis[T]!=INF; } inline void EK() { while(spfa()) { maxflow+=in[T]; ans+=in[T]*dis[T]; int x=T,i=pre[x]; while(x!=S) { e[i^1]+=in[T]; e[i]-=in[T]; x=ver[i^1];i=pre[x]; } } } int main() { //freopen("1.in","r",stdin); n=read();m=read();S=n*m*3+1;T=S+1; for(int i=1;i<=n;++i)scanf("%s",c[i]+1); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { pos[i][j]=++cnt; if(c[i][j]=='1')++sum,add(S,pos[i][j],1,0),b[i][j]=1; } for(int i=1;i<=n;++i)scanf("%s",c[i]+1); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(c[i][j]=='1')++sum1,add(pos[i][j],T,1,0),a[i][j]=1; if(sum!=sum1){printf("%d\n",-1);return 0;} for(int i=1;i<=n;++i)scanf("%s",c[i]+1); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { int w=(int)(c[i][j]-'0'); for(int k=1;k<=8;++k) { int xx=i+dx[k]; int yy=j+dy[k]; if(!pos[xx][yy])continue; add(pos[i][j]+n*m*2,pos[xx][yy]+n*m,INF,1); } if((!(a[i][j]^b[i][j]))||(!(w&1))) { add(pos[i][j]+n*m,pos[i][j],(w>>1),0); add(pos[i][j],pos[i][j]+n*m*2,(w>>1),0); } else { add(pos[i][j]+n*m,pos[i][j],(w>>1)+a[i][j]?1:0,0); add(pos[i][j],pos[i][j]+n*m*2,(w>>1)+b[i][j]?1:0,0); } } EK(); if(maxflow!=sum)printf("%d\n",-1); else printf("%d\n",ans); return 0; }
//#include<bits/stdc++.h> #include<iomanip> #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<queue> #include<deque> #include<cmath> #include<ctime> #include<cstdlib> #include<stack> #include<algorithm> #include<vector> #include<cctype> #include<utility> #include<set> #include<bitset> #include<map> #define INF 1000000000 #define ll long long #define min(x,y) (x>y?y:x) #define max(x,y) (x>y?x:y) #define RI register ll #define up(p,i,n) for(ll i=p;i<=n;++i) #define db double using namespace std; char buf[1<<15],*fs,*ft; inline char getc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int MAXN=25,maxn=MAXN*MAXN*24; int n,m,S,T,cnt,sum,sum1,flag,len=1,t,h,maxflow,ans; char c[MAXN][MAXN]; int a[MAXN][MAXN],pos[MAXN][MAXN],b[MAXN][MAXN]; int lin[maxn],nex[maxn],ver[maxn],e[maxn],e1[maxn]; int pre[maxn],in[maxn],vis[maxn],q[maxn],dis[maxn]; const int dx[9]={0,1,1,1,0,0,-1,-1,-1}; const int dy[9]={0,0,-1,1,1,-1,0,-1,1}; inline void add(int x,int y,int z,int z1) { ver[++len]=y;nex[len]=lin[x];lin[x]=len;e[len]=z;e1[len]=z1; ver[++len]=x;nex[len]=lin[y];lin[y]=len;e[len]=0;e1[len]=-z1; } inline int spfa() { for(int i=1;i<=T;++i)dis[i]=INF; t=h=0;q[++t]=S;vis[S]=1;dis[S]=0;in[S]=INF; while(h++<t) { int x=q[h];vis[x]=0; for(int i=lin[x];i;i=nex[i]) { int tn=ver[i]; if(!e[i])continue; if(dis[tn]>dis[x]+e1[i]) { dis[tn]=dis[x]+e1[i]; in[tn]=min(in[x],e[i]); pre[tn]=i; if(!vis[tn])q[++t]=tn,vis[tn]=1; } } } return dis[T]!=INF; } inline void EK() { while(spfa()) { maxflow+=in[T]; ans+=in[T]*dis[T]; int x=T,i=pre[x]; while(x!=S) { e[i^1]+=in[T]; e[i]-=in[T]; x=ver[i^1];i=pre[x]; } } } int main() { //freopen("1.in","r",stdin); n=read();m=read();S=n*m*3+1;T=S+1; for(int i=1;i<=n;++i)scanf("%s",c[i]+1); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { pos[i][j]=++cnt; if(c[i][j]=='1')++sum,add(S,pos[i][j],1,0),b[i][j]=1; } for(int i=1;i<=n;++i)scanf("%s",c[i]+1); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(c[i][j]=='1')++sum1,add(pos[i][j],T,1,0),a[i][j]=1; if(sum!=sum1){printf("%d\n",-1);return 0;} for(int i=1;i<=n;++i)scanf("%s",c[i]+1); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { int w=(int)(c[i][j]-'0'); for(int k=1;k<=8;++k) { int xx=i+dx[k]; int yy=j+dy[k]; if(!pos[xx][yy])continue; add(pos[i][j]+n*m*2,pos[xx][yy]+n*m,INF,1); } if((!(a[i][j]^b[i][j]))||(!(w&1))) { add(pos[i][j]+n*m,pos[i][j],w>>1,0); add(pos[i][j],pos[i][j]+n*m*2,w>>1,0); } else { --w; add(pos[i][j]+n*m,pos[i][j],(w>>1)+a[i][j],0); add(pos[i][j],pos[i][j]+n*m*2,(w>>1)+b[i][j],0); } } EK(); if(maxflow!=sum)printf("%d\n",-1); else printf("%d\n",ans); return 0; }