题目链接:https://www.luogu.com.cn/problem/P4014
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=211,M=4e4+11,inf=1<<29; 4 int n,a[N][N],st,ed,maxflow,maxx,minn; 5 int to[M],nxt[M],c[M],w[M],edge,head[N]; 6 int dis[N],incf[N],pre[N]; 7 bool vis[N]; 8 9 inline int re_ad() { 10 char ch=getchar(); int x=0,f=1; 11 while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } 12 while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 13 return x*f; 14 } 15 16 inline void addedge(int x,int y,int cc,int ww) { 17 ++edge,to[edge]=y,nxt[edge]=head[x],c[edge]=cc,w[edge]=ww,head[x]=edge; 18 ++edge,to[edge]=x,nxt[edge]=head[y],c[edge]=0,w[edge]=-ww,head[y]=edge; 19 } 20 21 inline bool SPFA_Min() { 22 memset(vis,false,sizeof(vis)); 23 memset(dis,0x3f,sizeof(dis)); 24 memset(pre,0,sizeof(pre)); 25 memset(incf,0x3f,sizeof(incf)); 26 queue<int> q; 27 q.push(st); 28 dis[st]=0,vis[st]=true; 29 while(!q.empty()) { 30 int u=q.front(),v; 31 vis[u]=false,q.pop(); 32 for(int i=head[u];i;i=nxt[i]) { 33 if(!c[i]) continue; 34 v=to[i]; 35 if(dis[u]+w[i]<dis[v]) { 36 dis[v]=dis[u]+w[i]; 37 incf[v]=min(incf[u],c[i]); 38 pre[v]=i; 39 if(!vis[v]) vis[v]=true,q.push(v); 40 } 41 } 42 } 43 // printf("min:dis[ed]: %d\n",dis[ed]); 44 if(dis[ed]==0x3f3f3f3f) return false; 45 return true; 46 } 47 48 inline void Update_Min() { 49 // printf("awa\n"); 50 int lj=ed,i; 51 while(lj!=st) { 52 i=pre[lj]; 53 c[i]-=incf[ed],c[i^1]+=incf[ed]; 54 lj=to[i^1]; 55 } 56 maxflow+=incf[ed]; 57 minn+=dis[ed]*incf[ed]; 58 } 59 60 inline bool SPFA_Max() { 61 memset(vis,false,sizeof(vis)); 62 memset(dis,0xcf,sizeof(dis)); 63 memset(pre,0,sizeof(pre)); 64 memset(incf,0x3f,sizeof(incf)); 65 queue<int> q; 66 q.push(st); 67 dis[st]=0,vis[st]=true; 68 // printf("ed: %d\n",dis[ed]); 69 while(!q.empty()) { 70 int u=q.front(),v; 71 // printf("max:u: %d %d\n",u,dis[u]); 72 vis[u]=false,q.pop(); 73 for(int i=head[u];i;i=nxt[i]) { 74 if(!c[i]) continue; 75 v=to[i]; 76 if(dis[u]+w[i]>dis[v]) { 77 dis[v]=dis[u]+w[i]; 78 incf[v]=min(incf[u],c[i]); 79 pre[v]=i; 80 if(!vis[v]) vis[v]=true,q.push(v); 81 } 82 } 83 } 84 // printf("max:dis[ed]: %d\n",dis[ed]); 85 if(dis[ed]==0xcfcfcfcf) return false; 86 return true; 87 } 88 89 inline void Update_Max() { 90 int lj=ed,i; 91 while(lj!=st) { 92 i=pre[lj]; 93 c[i]-=incf[ed],c[i^1]+=incf[ed]; 94 lj=to[i^1]; 95 } 96 maxflow+=incf[ed]; 97 maxx+=dis[ed]*incf[ed]; 98 } 99 100 int main() 101 { 102 n=re_ad(); 103 for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) a[i][j]=re_ad(); 104 st=0,ed=n*2+1,edge=1,maxflow=0; 105 memset(head,0,sizeof(head)); 106 for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) addedge(i,j+n,1,a[i][j]); 107 for(int i=1;i<=n;++i) addedge(st,i,1,0),addedge(i+n,ed,1,0); 108 while(SPFA_Min()) Update_Min(); 109 // printf("endif:min:%d\n",minn); 110 111 st=0,ed=n*2+1,edge=1,maxflow=0; 112 memset(head,0,sizeof(head)); 113 for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) addedge(i,j+n,1,a[i][j]); 114 for(int i=1;i<=n;++i) addedge(st,i,1,0),addedge(i+n,ed,1,0); 115 while(SPFA_Max()) Update_Max(); 116 printf("%d\n%d\n",minn,maxx); 117 return 0; 118 }