【BZOJ 1189】 [HNOI2007]紧急疏散evacuate

添加数据的人的ID就在原题目下面 大家知道该怎么做了吧

还有一点 读入是要小心 新增的数据格式好像有问题 用%s 读入整行吧

题解

没加数据时都会做
新加数据后 我们应把每个D bfs一遍 求出每个. 到他的距离
把每个D分成很多个 每个代表一个时间 相邻两个时间连边 表示可以=待
按照.D的距离分别连边到对应的D

最后 二分时 把Dt连边 权值为1 连到mid秒时停止

额 差不多了 说具体就不好了 自己实现吧 具体过程看个人习惯 不要怕开变量!!!
下面是 原汁原味的带注释代码 我自己都不想读 每个变量代表什么意思 我都要看一会......

代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define MAXN 1000000
#define INF 100000000
using namespace std;
int xx[5]={0,0,0,1,-1};
int yy[5]={0,1,-1,0,0};
int g[MAXN],num[MAXN],nnext[MAXN],flow[MAXN],tot=2;
void Add(int x,int y,int f){/*cout<<x<<' '<<y<<' '<<f<<endl;*/nnext[tot]=g[x];g[x]=tot;num[tot]=y;flow[tot]=f;tot++;}
int d[MAXN],team[MAXN],head,tail;
int id[21][21],idt[401][10000],cnt=0;
int a[22][22];
int n,m,s,t;
int tt[MAXN],ntt=0,nans=0;
int tmpflow[MAXN],tmpg[MAXN];
int dis[401][401];
int now;
bool bfs()
{
	head=tail=0;memset(d,0,sizeof(d));
	d[s]=1;team[++tail]=s;
	while(head<tail)
	{
		int x=team[++head]; //cout<<x<<' '<<d[x]<<endl;
		for(int i=g[x];i;i=nnext[i])
			if(d[num[i]]==0&&flow[i]!=0)
				d[num[i]]=d[x]+1,team[++tail]=num[i];
	}
//	cout<<d[t]<<endl;
	if(d[t]==0) return false;
	return true;
}
int dfs(int x,int mmin)
{
	if(x==t) return mmin;
	int tmp,f=0;
	for(int i=g[x];i;i=nnext[i])
		if(d[num[i]]==d[x]+1&&flow[i]!=0&&(tmp=dfs(num[i],min(mmin,flow[i]))))
		{
			flow[i]-=tmp;
			flow[i^1]+=tmp;
			f+=tmp,mmin-=tmp;
			if(mmin==0) return f;
		}
	return f;
}
bool F(int mid)
{
	for(int i=now;i<=tot;i++) nnext[tot]=0;
	for(int i=0;i<=now;i++) flow[i]=tmpflow[i];
	for(int i=0;i<=cnt;i++) g[i]=tmpg[i]; g[t]=tmpg[t]; //cout<<g[t]<<endl;
	tot=now;//cout<<cnt<<endl;
	for(int i=1;i<=ntt;i++)
		for(int j=1;j<=mid;j++)
		{
			int tmp=tt[i];
			Add(idt[tmp][j],t,1);
			Add(t,idt[tmp][j],0);
		}
//	cout<<"fs";
	int ans=0;
	while(bfs()) ans+=dfs(s,INF);
//	cout<<mid<<' '<<ans<<endl;
	if(ans==nans) return true;
	return false;
}
int q[MAXN][2];
bool b[21][21];
void spfa(int x,int y)
{
	head=tail=0;int thiss =id[x][y];
	q[++tail][0]=x,q[tail][1]=y;dis[thiss][thiss]=1;
	while(head<tail)
	{
		x=q[++head][0],y=q[head][1];b[x][y]=false; int nowd=dis[thiss][id[x][y]];
		for(int i=1;i<=4;i++)
		{
			int tx=x+xx[i],ty=y+yy[i];
			if(tx<1||tx>n||ty<1||ty>m) continue;
			int idd=id[tx][ty];
			if(a[tx][ty]==1&&dis[thiss][idd]==0||dis[thiss][idd]>nowd)
			{
				dis[thiss][idd]=nowd+1;
				if(!b[tx][ty]) 
				{
					b[tx][ty]=true;
					q[++tail][0]=tx;
					q[tail][1]=ty;
				}
			}	
		}
	}
	idt[thiss][1]=++cnt;
	for(int i=2;i<=1000;i++)
		idt[thiss][i]=++cnt,Add(cnt-1,cnt,INF),Add(cnt,cnt-1,0);	
	
	dis[thiss][thiss]=0;
	for(int i=1;i<=n*m;i++)
	if(dis[thiss][i]!=0)
	{
		dis[thiss][i]--;
		int tmp=dis[thiss][i]; 
	//	cout<<i<<' '<<idt[thiss][tmp]<<endl;
		Add(i,idt[thiss][tmp],1);
		Add(idt[thiss][tmp],i,0);
	}
}
char ss[200];
int main()
{
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
	/*	char c=getchar();
		for(int j=1;j<=m;j++)
		{
			id[i][j]=++cnt;

			c=getchar();
			if(c=='X') a[i][j]=0;
			if(c=='.') a[i][j]=1,nans++;
			if(c=='D') a[i][j]=2;
		}*/
		scanf("%s",ss+1);
		for(int j=1;j<=m;j++)
		{
			id[i][j]=++cnt;

			if(ss[j]=='X') a[i][j]=0;
			if(ss[j]=='.') a[i][j]=1,nans++;
			if(ss[j]=='D') a[i][j]=2;
		}
	}
	s=0;t=1000000-1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]==2)
				spfa(i,j),tt[++ntt]=id[i][j];
			else if(a[i][j]==1)
				Add(s,id[i][j],1),
				Add(id[i][j],s,0);
	now=tot;
	for(int i=0;i<=now;i++) tmpflow[i]=flow[i];
	for(int i=0;i<=cnt;i++) tmpg[i]=g[i]; tmpg[t]=g[t];
	
//	cout<<cnt<<endl;
	int L=0,R=1000;
	while(L<R)
	{
		int mid=(L+R)/2;
		if(F(mid)) R=mid;
		else L=mid+1;
	}
	if(L==1000)  cout<<"impossible";
	else cout<<L<<endl;

	return 0;
}
posted @ 2016-01-13 17:15  sxb_201  阅读(209)  评论(0编辑  收藏  举报