您的位置:首页 > 其它

HUNAN 11567 Escaping (最大流)

2015-08-10 13:20 260 查看
http://acm.hunnu.edu.cn/online/?action=problem&type=list&courseid=0&querytext=&pageno=31

一个n*n的房间,每个点可能有人和救生装备,两个n*n的矩阵,第一个代表每个点有多少个人,第二个矩阵代表每个点有多少个救生装备,然后每个人在t秒内要是找不到救生装备就会死亡,问能够逃生的最大人数。

如果当前点有人则源点和当前点相连,流量为人数,如果当前点有救生装备,则当前点和汇点相连,流量为装备的数量.

然后中间如果人和装备的最短距离小于等于t,则人和装备相连,流量为INF,因为同一条边人可以走多次.

#include<iostream>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stdio.h>
#include<cstdlib>
using namespace std;

const int mmax=12;
const int inf=0x3f3f3f3f;
int list[220],dis[220],gap[220],node;
int source,sink,Vs;

struct E
{
int to,c,next;
}edg[10000002];

void addedg(int from,int to,int value)
{
edg[node].to = to,  edg[node].c = value,  edg[node].next = list[from],   list[from] = node++;
edg[node].to = from,edg[node].c = 0,      edg[node].next = list[to],     list[to] = node ++;
}

int dfs(int src,int aug)
{
if(src == sink) return aug;
int flow = 0,mid_d = Vs-1;
for(int j = list[src];j != -1; j = edg[j].next)
if(edg[j].c)
{
if(dis[src] == dis[edg[j].to]+1)
{
int t = dfs(edg[j].to,min(aug-flow,edg[j].c));
edg[j].c -= t;
edg[j^1].c += t;
flow += t;
if(dis[source] >= Vs)    return flow;
if(aug == flow) break;
}
mid_d = min(mid_d,dis[edg[j].to]);
}
if(!flow)
{
if(!(--gap[dis[src]]))    dis[source] = Vs;
dis[src] = mid_d+1;
++gap[dis[src]];
}
//printf("%d\n",flow);
return flow;
}

int maxflow_sap(int src,int ed)  //1  m
{
int ans = 0;
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
gap[0] = Vs = ed;
source = src, sink = ed;

while(dis[source] < Vs)
{
ans += dfs(source,inf);
// printf("%d\n",ans);
}
return ans;
}

int main()
{
//freopen("a.txt","r",stdin);
int n,t;
int boat[mmax][mmax];
int man[mmax][mmax];
while(~scanf("%d%d",&n,&t))
{
node = 0;
memset(list,-1,sizeof(list));

for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&man[i][j]);//源点和人相连
if(man[i][j]>0) addedg(2*n*n+1,i*n+j,man[i][j]);
//printf("%d ",man[i][j]);
}
//printf("\n");
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&boat[i][j]);//装备和汇点相连
if(boat[i][j]>0) addedg(i*n+j+n*n,2*n*n+2,boat[i][j]);
//printf("%d ",boat[i][j]);
}
//printf("\n");
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(man[i][j]>0)
{
for(int k=0;k<n;k++)
{
for(int p=0;p<n;p++)
{
if(boat[k][p]>0&&abs(k-i)+abs(p-j)<=t)
{   //人与装备相连
addedg(i*n+j,k*n+p+n*n,inf);
//printf("%d %d %d %d\n",i,j,k,p);
}
}
}
}
}
}
int ans=maxflow_sap(2*n*n+1,2*n*n+2);
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: