Codeforces 78E Evacuation

来源:互联网 发布:淘宝上的麻将游戏开发 编辑:程序博客网 时间:2024/05/09 20:43

构图的思路与POJ 2391是一样的,对于从一个初级源点s出发的流,如果可到达的点是受限制的,可以先把这些受限制的点都找出来,拆点拆成i->i',然后,s向i'连边,

最后,超级源点S向每个初级源点s连边,每个点i'向汇点连边


为什么要这么做?因为既然从s出发的流是受限制的,我们可以在s上限制它,但也必须在每个s可到的点上限制它,而网络流中是不分这部分流是从哪个源点过来的,因此,无法在下面的点上限制该流,那么,我们必须采取某种策略,使得该流从s出发后不会走到限制范围外的点,方法就是处理出所有受限制的点,直接连边,并且,这些流只能到达汇点

一组不这么做会错的数据

5 1
0YZ52
3Y481
66Y68
Y1665
35923

9YZ89
2Y876
08Y19
Y1891
24689

答案是88,不这么拆点答案就是89,在这里wa了很久

另外,这道题还要预先处理出爆炸点到每个实验室的最短路,以及每个有科学家的实验室到所有具有救生舱的实验室的最短路,如果实验室a到实验室b的最短路径小于等于爆炸点到实验室b的最短路径,就可以连边a->b'

由于边权为1,可以用bfs实现


代码:

#include<iostream>#include<memory.h>#include<string>#include<cstdio>#include<algorithm>#include<math.h>#include<stack>#include<queue>#include<vector>#include<map>using namespace std;const int MAX=10005;const int inf=1<<30;struct node {int u,v,c,next;}g[MAX*10];struct Node {int x,y,step;};int adj[MAX],dis[MAX],cur[MAX],pre[MAX],num[MAX],n,e,s,t,vn,T;int sx,sy,dir[4][2]={1,0,-1,0,0,1,0,-1};int flag[15][15],vis[15][15];char mat1[15][15],mat2[15][15];bool in(int x,int y){if(x<1||x>n||y<1||y>n)return false;return true;}void add(int u,int v,int c)  {       g[e].u=u; g[e].v=v; g[e].c=c; g[e].next=adj[u]; adj[u]=e++;       g[e].u=v; g[e].v=u; g[e].c=0; g[e].next=adj[v]; adj[v]=e++;      //if(u==s||v==t)     //if(u==12+n*n&&v==17) //cout<<u<<" "<<v<<" "<<c<<endl; }  void bfs1(){queue<Node>que;Node now,next;now.x=sx; now.y=sy; now.step=0;que.push(now);memset(flag,0x7f,sizeof(flag));memset(vis,0,sizeof(vis));vis[now.x][now.y]=1;while(!que.empty()){now=que.front();que.pop();flag[now.x][now.y]=now.step;if(now.step>T)break;for(int i=0;i<4;i++){int xx=now.x+dir[i][0];int yy=now.y+dir[i][1];if(in(xx,yy)&&mat1[xx][yy]!='Y'&&!vis[xx][yy]){next.x=xx; next.y=yy; next.step=now.step+1;vis[xx][yy]=1;que.push(next);}}}}void bfs2(int i,int j){queue<Node>que;Node now,next;now.x=i; now.y=j; now.step=0;que.push(now);memset(vis,0,sizeof(vis));vis[now.x][now.y]=1;while(!que.empty()){now=que.front();que.pop();if(now.step>T)break;if(flag[now.x][now.y]<now.step)continue;if(flag[now.x][now.y]==now.step&&(mat2[now.x][now.y]<'1'||mat2[now.x][now.y]>'9'))continue;if(mat2[now.x][now.y]>='1'&&mat2[now.x][now.y]<='9'){if(now.x!=i||now.y!=j)add((i-1)*n+j,(now.x-1)*n+now.y+n*n,inf);if(flag[now.x][now.y]==now.step)continue;}for(int i=0;i<4;i++){int xx=now.x+dir[i][0];int yy=now.y+dir[i][1];if(in(xx,yy)&&mat1[xx][yy]!='Y'&&!vis[xx][yy]){next.x=xx; next.y=yy; next.step=now.step+1;vis[xx][yy]=1;que.push(next);}}}}int sap()    {        int i,u,v,flag,aug=inf,flow=0;        for(i=0;i<=vn;i++)        {            cur[i]=adj[i];            num[i]=dis[i]=0;        }        num[0]=vn;        pre[s]=u=s;        while(dis[s]<vn)        {            flag=0;            for(i=cur[u];i!=-1;i=g[i].next)            {                v=g[i].v;                if(g[i].c&&dis[u]==dis[v]+1)                {                    flag=1;                    aug=min(aug,g[i].c);                    pre[v]=u;                    cur[u]=i;                    u=v;                    if(u==t)                    {                        flow+=aug;                        while(u!=s)                        {                            u=pre[u];                            g[cur[u]].c-=aug;                            g[cur[u]^1].c+=aug;                        }                        aug=inf;                    }                    break;                }            }            if(flag)                continue;            if(--num[dis[u]]==0)                break;            for(dis[u]=vn,i=adj[u];i!=-1;i=g[i].next)            {                v=g[i].v;                if(g[i].c&&dis[v]<dis[u])                {                    dis[u]=dis[v];                    cur[u]=i;                }            }            dis[u]++;            num[dis[u]]++;            u=pre[u];        }        return flow;    }   int main(){int i,j,k;while(scanf("%d%d",&n,&T)!=EOF){memset(adj,-1,sizeof(adj));e=0;s=0;t=n*n+n*n+1;vn=t+1;for(i=1;i<=n;i++){scanf("%s",mat1[i]+1);for(j=1;j<=n;j++){if(mat1[i][j]>='1'&&mat1[i][j]<='9'){add(s,(i-1)*n+j,mat1[i][j]-'0');}if(mat1[i][j]=='Z'){sx=i;sy=j;}}}for(i=1;i<=n;i++){scanf("%s",mat2[i]+1);for(j=1;j<=n;j++){add((i-1)*n+j,(i-1)*n+j+n*n,inf);if(mat2[i][j]>='1'&&mat2[i][j]<='9')add((i-1)*n+j+n*n,t,mat2[i][j]-'0');}}bfs1();for(i=1;i<=n;i++){for(j=1;j<=n;j++){if(mat1[i][j]>='1'&&mat1[i][j]<='9')bfs2(i,j);}}i=1;printf("%d\n",sap());/*for(i=1;i<=100;i++){for(j=adj[i];j!=-1;j=g[j].next){if(g[j].v==t)printf("%d %d\n",i,g[j^1].c);}} *//*for(i=1;i<e;i+=2){if(g[i].u==g[i].v+n*n)continue;printf("%d %d %d\n",g[i].v>n*n?g[i].v-n*n:g[i].v,g[i].u>n*n?g[i].u-n*n:g[i].u,g[i].c);} */}return 0;}


原创粉丝点击