【BZOJ 1189】 [HNOI2007]紧急疏散evacuate
添加数据的人的ID就在原题目下面 大家知道该怎么做了吧
还有一点 读入是要小心 新增的数据格式好像有问题 用%s
读入整行吧
题解
没加数据时都会做
新加数据后 我们应把每个D
bfs一遍 求出每个.
到他的距离
把每个D
分成很多个 每个代表一个时间 相邻两个时间连边 表示可以=待
按照.
到D
的距离分别连边到对应的D
最后 二分时 把D
向t
连边 权值为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;
}