您的位置:首页 > 理论基础 > 计算机网络

BOJ313 Candy [网络流 dinic]

2013-03-21 12:42 417 查看
链接:
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

;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: