链接:
http://acm.bupt.edu.cn/onlinejudge/newoj/showProblem/show_problem.php?problem_id=313
题意:
给定一个50*50的矩阵,矩阵中每个格子代表一个孩子手中的糖果。
每个孩子可以向上下左右相邻的孩子传递至多一个糖果。
提前:
注意题意中的“至多”,很多“至多'问题都可以应用网络流来解决。
之前一直写的dinic模板过不了,之前的dinic模板是bfs进行分层【level[v]=level[now]+1】。
但是这个构图和以前的不同,每个点到源点和汇点都有直接相邻。
所以可以直接省略bfs这个步骤。【如果不省略bfs这个步骤,就一直tle不停的tle直到天荒地老】
#include<iostream> #include<fstream> #include<map> #include<vector> #include<string> #include<memory.h> #include<cmath> #include<algorithm> #include<queue> #define Min(a,b) (a<b?a:b) #define Max(a,b) (a>b?a:b) #define Abs(a) (a>0?(a):-(a)) #define llong long long int using namespace std; const int N=55,M=2505,inf=0x7fffffff; int n,m; int mat[N][N]; struct Edge { int v; int w; int next; }edge[M*20]; int edgehead[M]; int s,t; int mx[4]={-1,1,0,0}; int my[4]={0,0,-1,1}; int k=1; bool vis[M]; void insert(int u,int v,int w) { edge[++k].v=v; edge[k].w=w; edge[k].next = edgehead[u]; edgehead[u]=k; edge[++k].v=u; edge[k].w=0; edge[k].next=edgehead[v]; edgehead[v]=k; } int dinic(int now,int mi) { if(now==t) return mi; vis[now]=true; int sum=0; for(int i = edgehead[now];i && sum<mi;i=edge[i].next) { int v = edge[i].v; int w = edge[i].w; if(!vis[v]&&w) { int ret=dinic(v,Min(w,mi-sum)); edge[i].w -= ret; edge[i^1].w +=ret; sum+=ret; } } return sum; } int solve() { int ret=0,sum=0; memset(vis,0,sizeof(vis)); while(ret=dinic(s,inf)) { sum+=ret; memset(vis,0,sizeof(vis)); } return sum; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(edge,0,sizeof(edge)); memset(edgehead,0,sizeof(edgehead)); k=1; s = n*m; t = s+1; int sum=0; for(int i =0;i<n;i++) { for(int j=0;j<m;j++) { scanf("%d",mat[i]+j); sum+=mat[i][j]; } } if(sum%(n*m)) { printf("NO\n"); continue; } int avg = sum/(n*m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) { insert(s,i*m+j,mat[i][j]); insert(i*m+j,t,avg); } for(int i =0;i<n;i++) { for(int j=0;j<m;j++) { for(int k=0;k<4;k++) { int ii = i+my[k]; int jj = j+mx[k]; if(ii>=0&&ii<n&&jj>=0&&jj<m) { insert(i*m+j,ii*m+jj,1); } } } } if(sum==solve()) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }