http://www.lydsy.com/JudgeOnline/problem.php?id=2127
对于每个人都记一个点,
S->A 理[i][j]+理cost[A][B]/2 A->T 理[i][j]+理cost[A][B]/2
S->A 文[i][j]+文cost[A][B]/2 A->T 文[i][j]+文cost[A][B]/2
A<->B 理cost[i][j]/2+文cost[i][j]/2
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #define inf 0x7fffffff 7 int w[105][105][2],flow[200005],next[200005],first[200005],nodes,T,S; 8 int go[200005],op[200005],dis[200005],cnt[200005],tot,m,n,id[105][105]; 9 int read(){ 10 int t=0,f=1;char ch=getchar(); 11 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 12 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 13 return t*f; 14 } 15 void insert(int x,int y,int z){ 16 tot++; 17 go[tot]=y; 18 next[tot]=first[x]; 19 first[x]=tot; 20 flow[tot]=z; 21 } 22 void add(int x,int y,int z){ 23 insert(x,y,z);op[tot]=tot+1; 24 insert(y,x,0);op[tot]=tot-1; 25 } 26 void add2(int x,int y,int z){ 27 insert(x,y,z);op[tot]=tot+1; 28 insert(y,x,z);op[tot]=tot-1; 29 } 30 int dfs(int x,int f){ 31 if (x==T) return f; 32 int mn=nodes,sum=0; 33 for (int i=first[x];i;i=next[i]){ 34 int pur=go[i]; 35 if (flow[i]&&dis[pur]+1==dis[x]){ 36 int save=dfs(pur,std::min(f-sum,flow[i])); 37 sum+=save; 38 flow[i]-=save; 39 flow[op[i]]+=save; 40 if (sum==f||dis[S]>=nodes) return sum; 41 } 42 if (flow[i]) mn=std::min(mn,dis[pur]); 43 } 44 if (sum==0){ 45 cnt[dis[x]]--; 46 if (cnt[dis[x]]==0){ 47 dis[S]=nodes; 48 }else{ 49 dis[x]=mn+1; 50 cnt[dis[x]]++; 51 } 52 } 53 return sum; 54 } 55 int main(){ 56 n=read();m=read(); 57 S=0; 58 T=n*m+1; 59 nodes=T+1; 60 int sz=0,ans=0; 61 for (int i=1;i<=n;i++) 62 for (int j=1;j<=m;j++) 63 id[i][j]=++sz; 64 for (int i=1;i<=n;i++) 65 for (int j=1;j<=m;j++) 66 w[i][j][0]=read(),ans+=w[i][j][0],w[i][j][0]*=2; 67 for (int i=1;i<=n;i++) 68 for (int j=1;j<=m;j++) 69 w[i][j][1]=read(),ans+=w[i][j][1],w[i][j][1]*=2; 70 for (int i=1;i<=n-1;i++) 71 for (int j=1;j<=m;j++){ 72 int x=read();ans+=x; 73 w[i][j][0]+=x;w[i+1][j][0]+=x; 74 add2(id[i][j],id[i+1][j],x); 75 } 76 for (int i=1;i<=n-1;i++) 77 for (int j=1;j<=m;j++){ 78 int x=read();ans+=x; 79 w[i][j][1]+=x;w[i+1][j][1]+=x; 80 add2(id[i][j],id[i+1][j],x); 81 } 82 for (int i=1;i<=n;i++) 83 for (int j=1;j<=m-1;j++){ 84 int x=read();ans+=x; 85 w[i][j][0]+=x;w[i][j+1][0]+=x; 86 add2(id[i][j],id[i][j+1],x); 87 } 88 for (int i=1;i<=n;i++) 89 for (int j=1;j<=m-1;j++){ 90 int x=read();ans+=x; 91 w[i][j][1]+=x;w[i][j+1][1]+=x; 92 add2(id[i][j],id[i][j+1],x); 93 } 94 for (int i=1;i<=n;i++) 95 for (int j=1;j<=m;j++) 96 add(S,id[i][j],w[i][j][0]),add(id[i][j],T,w[i][j][1]); 97 int Mnflow=0; 98 while (dis[S]<nodes) Mnflow+=dfs(S,inf); 99 printf("%d ",ans-Mnflow/2); 100 }