• 【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;
    }
    
  • 相关阅读:
    智能佳 金刚足球机器人 竞赛机器人 智能机器人
    DIY小能手|别买电动滑板车了,咱做一台吧
    !!2016/02/22——当日买入——事后追悔,总结经验,忘记了买票的初衷!
    20160222深夜 支撑与阻力的问题,突破要不要买,回踩要不要接
    2016/2/4——昨天操作错误
    C语言 · 瓷砖铺放
    C语言 · 字符串编辑
    C语言 · 比较字符串
    C语言 · 3000米排名预测
    C语言 · 陶陶摘苹果2
  • 原文地址:https://www.cnblogs.com/ofsxb/p/5127878.html
Copyright © 2020-2023  润新知