网络流最小割 王者之剑
不用考虑走的方法,因为一旦合法,即不同时取相邻的两个,一定能达到。
所以只用考虑怎么取就行了。
把棋盘黑白染色,S到黑点建权值为val的边,白点到T建权值为val的边,
然后把相邻的黑白点建一条为inf的边。
求最小割。
不得不提一句:边从零开始建和从一开始建一个wa一个a。。
^时相应的正边和反边必须对应。(卡了好久,身败名裂)
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> #define inf 100000000 using namespace std; int n,m,a[505][505],b[505][505],S=0,T,cnt,c[505][505]; int dep[100005],e,adj[100005],sum=0; struct node { int v,l,next; } lu[100005]; void add(int u,int v,int l) {lu[e].v=v;lu[e].l=l;lu[e].next=adj[u];adj[u]=e++;} inline int bfs() { memset(dep,0,sizeof(dep)); queue<int> q; dep[S]=1; q.push(S); while(!q.empty()) { int x=q.front();q.pop(); for(int i=adj[x];i!=-1;i=lu[i].next) { int to=lu[i].v; if(lu[i].l&&!dep[to]) { dep[to]=dep[x]+1; q.push(to); if(to==T)return 1; } } } return 0; } inline int read() { int su=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch<='9'&&ch>='0'){su=su*10+ch-'0';ch=getchar();} return su; } inline int dfs(int now,int f){ if(now==T){ return f; } int tmp=f; for(int i=adj[now];i!=-1;i=lu[i].next){ int to=lu[i].v,w=lu[i].l; if(w&&tmp&&dep[to]==dep[now]+1){ int k=dfs(to,min(w,tmp)); if(!k){ dep[to]=0; continue; } lu[i].l-=k; lu[i^1].l+=k; tmp-=k; } } return f-tmp; } int yjn() { freopen("Excalibur.in","r",stdin); freopen("Excalibur.out","w",stdout); scanf("%d%d",&n,&m); memset(adj,-1,sizeof(adj)); for(int i=1;i<=n;i++) { int k=0; if(i&1)k=1; for(int j=1;j<=m;j++) { a[i][j]=++cnt; b[i][j]=k;k^=1; c[i][j]=read(); sum+=c[i][j]; } } /* for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) cout<<b[i][j]<<" "; cout<<endl; }*/ T=cnt+3; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(b[i][j]) {add(a[i][j],T,c[i][j]),add(T,a[i][j],0);} else {add(S,a[i][j],c[i][j]),add(a[i][j],S,0);} } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(b[i][j]==0) { if(i!=1){add(a[i][j],a[i-1][j],inf),add(a[i-1][j],a[i][j],0);} if(i!=n){add(a[i][j],a[i+1][j],inf),add(a[i+1][j],a[i][j],0);} if(j!=1){add(a[i][j],a[i][j-1],inf),add(a[i][j-1],a[i][j],0);} if(j!=m){add(a[i][j],a[i][j+1],inf),add(a[i][j+1],a[i][j],0);} } } int ans=0; while(bfs()) ans+=dfs(S,inf); cout<<(sum-ans); } int qty=yjn(); int main(){;}