hdu 1733 Escape

来源:互联网 发布:java treemap 红黑树 编辑:程序博客网 时间:2024/05/19 04:53

拆点,假设 T 时间可以完全撤离,那么每个点就拆成2*T个点,为什么是2*T个点呢?因为在两点间还要有一个流量的限制,所以个数变成T的两倍。点和点之间的容量限制很原始,因为每位置最多只能有一个人,所以正向流量是1,因为时间是正向流动的,所以逆向容量是0.

最后根据实验,这题的答案不会超过50。亏哥还用了个二分搜索加dinic,早知道直接用ek加暴力枚举,更快更好写!!!如果不是最大流就增加一层,这样的话复杂度最多50*E ,100ms之内估计就能搞定~

#include<iostream>#include<vector>#include<algorithm>#include<cstdio>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<cmath>#include<cassert>#include<cstring>#include<iomanip>using namespace std;#ifdef _WIN32#define i64 __int64#define out64 "%I64d\n"#define in64 "%I64d"#else#define i64 long long#define out64 "%lld\n"#define in64 "%lld"#endif#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)#define FFD(i,a)        for( int i = (a)-1 ; i >= 0 ; i --)#define S64(a)          scanf(in64,&a)#define SS(a)           scanf("%d",&a)#define LL(a)           ((a)<<1)#define RR(a)           (((a)<<1)+1)#define SZ(a)           ((int)a.size())#define PP(n,m,a)puts("---");FF(i,n){FF(j,m)cout << a[i][j] << ' ';puts("");}#define pb              push_back#define CL(Q)           while(!Q.empty())Q.pop()#define MM(name,what)   memset(name,what,sizeof(name))#define read            freopen("in.txt","r",stdin)#define write           freopen("out.txt","w",stdout)const int inf = 0x3f3f3f3f;const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;const double oo = 10e9;const double eps = 10e-8;const double pi = acos(-1.0);const int maxn = 256 * 50 * 2 + 1;const int end = 256 * 50 *2;const int ac = 256;const int dir[5][2]={{0,0},{1,0},{0,1},{-1,0},{0,-1}};struct zz{    int c;    int from;    int to;    int id;}zx,tz;vector<zz>g[maxn];queue<int>q;int cen[maxn];bool vis[20][20];int n,m,total;char cs[20][20];bool yes(int x,int y){       if(1<=x && x<=n && 1<=y && y<=m)    {        return true;    }                       return false;}inline int num(int x , int y , int xx = 0){       return (x-1)*16 + y + ac * xx;}int dx(int xx){    return (((xx-1) % ac + 1)-1) / 16 + 1;}int dy(int xx){       return (((xx-1) % ac + 1)-1) % 16 + 1;}int dn(int xx)              {    return (xx - 1) / ac + 1;       }void build(int t){    FF(i,maxn)    {        g[i].clear();    }       FOR(i,1,n) FOR(j,1,m)    {        if(cs[i][j]=='X')        {            zx.from = 0;                zx.to = num(i,j);            zx.id = g[zx.to].size();            zx.c =1;            g[0].pb ( zx );            swap(zx.from,zx.to);            zx.id = g[0].size() - 1;            zx.c = 0;            g[zx.from].pb(zx);        }    }        int nowx,nowy;    int from,to;    FOR(k,1,t)    {        FOR(i,1,n) FOR(j,1,m)        {            if(cs[i][j] == '#')            {                continue;            }                from = num(i,j, 2*k - 2);            FF(e,5)                 {                nowx = i + dir[e][0];                nowy = j + dir[e][1];                if(!yes(nowx,nowy))                {                    continue;                }                to = num(nowx,nowy,2*k-1);                if(cs[nowx][nowy] != '#')                {                    zx.from =  from;                    zx.to = to;                    zx.c = 1;                    zx.id = g[to].size();                     g[from].pb(zx);                    swap(zx.from,zx.to);                    zx.c = 0;                    zx.id = g[from].size()-1;                    g[to].pb(zx);                    }                 }            from = num(i,j,2*k - 1);            to = num(i,j,2*k);            zx.from = from;            zx.to = to;            zx.id = g[to].size();            zx.c=1;            g[from].pb(zx);            swap(zx.from,zx.to);            zx.c = 0;            zx.id = g[from].size() - 1;            g[to].pb(zx);             if(cs[i][j] == '@')            {                zx.from = to;                zx.to = end;                zx.id = g[end].size();                zx.c = 1;                g[zx.from].pb(zx);                swap(zx.from,zx.to);                zx.c=0;                zx.id=g[to].size()-1;                g[zx.from].pb(zx);              }        }            }       return ;}bool bfs0(){    CL(q);    MM(vis,false);    FOR(i,1,n) FOR(j,1,m)    {          if(cs[i][j]=='@')        {            q.push(num(i,j));            vis[i][j] = true;        }    }           int nowx,nowy,now;    while(!q.empty())    {        now = q.front();        q.pop();        FOR(i,1,4)        {            nowx = dx(now) + dir[i][0];            nowy = dy(now) + dir[i][1];            if(cs[nowx][nowy] != '#' && !vis[nowx][nowy] && yes(nowx,nowy))            {                   q.push(num(nowx,nowy));                vis[nowx][nowy] = true;            }        }    }    FOR(i,1,n) FOR(j,1,m)    {        if(cs[i][j] == 'X' && vis[i][j] == false)        {                                               return false;        }    }                        return true;  }                bool bfs(){      CL(q);    MM(cen,-1);    q.push(0);    cen[0]=0;    int now,to;    while(!q.empty())    {        now = q.front();        q.pop();        FF(i,g[now].size())         {            to = g[now][i].to;            if(g[now][i].c > 0 && cen[to] == -1)            {                   cen[to] = cen[now] + 1;                q.push(to);            }        }        }    return cen[end] != -1;}int dfs(int flow = inf , int now = 0){       if(now == end)      {           return flow;    }    int temp,sum=0;    int to;    FF(i,g[now].size())    {        to = g[now][i].to;        if(cen[to] == cen[now] + 1 && flow > sum && g[now][i].c >0 )        {            temp = dfs ( min ( g[now][i].c , flow - sum ) , to );            sum += temp;            g[now][i].c -= temp;            g[to][g[now][i].id].c += temp;        }    }    if(!sum) cen[now] = -1;    return sum;}bool dinic(){      int ans=0;    while(bfs())    {        ans += dfs();    }         if(ans == total)    {        return true;    }                       return false;}int bin(int l=1,int r=50){    if( !bfs0 () )    {           return -1;    }          int mid;    while(l<r)    {        mid = (l+r)/2;        build(mid);        if(dinic())        {            r = mid;                }           else        {            l = mid + 1;        }    }        return l;     }int main(){    while(cin>>n>>m)    {           total = 0;        FOR(i,1,n) FOR(j,1,m)           {            cin>>cs[i][j];            if(cs[i][j]=='X')            {                total++;            }        }        cout<<bin()<<endl;    }    return 0;    }


稍微改了一下,在当前的剩余图中继续增加流量,140ms


#include<iostream>#include<vector>#include<algorithm>#include<cstdio>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<cmath>#include<cassert>#include<cstring>#include<iomanip>using namespace std;#ifdef _WIN32#define i64 __int64#define out64 "%I64d\n"#define in64 "%I64d"#else#define i64 long long#define out64 "%lld\n"#define in64 "%lld"#endif#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)#define FFD(i,a)        for( int i = (a)-1 ; i >= 0 ; i --)#define S64(a)          scanf(in64,&a)#define SS(a)           scanf("%d",&a)#define LL(a)           ((a)<<1)#define RR(a)           (((a)<<1)+1)#define SZ(a)           ((int)a.size())#define PP(n,m,a)puts("---");FF(i,n){FF(j,m)cout << a[i][j] << ' ';puts("");}#define pb              push_back#define CL(Q)           while(!Q.empty())Q.pop()#define MM(name,what)   memset(name,what,sizeof(name))#define read            freopen("in.txt","r",stdin)#define write           freopen("out.txt","w",stdout)const int inf = 0x3f3f3f3f;const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;const double oo = 10e9;const double eps = 10e-8;const double pi = acos(-1.0);const int maxn = 256 * 50 * 2 + 1;const int end = 256 * 50 *2;const int ac = 256;const int dir[5][2]={{0,0},{1,0},{0,1},{-1,0},{0,-1}};struct zz{    int c;    int from;    int to;    int id;}zx,tz;vector<zz>g[maxn];queue<int>q;int cen[maxn];bool vis[20][20];int n,m,total,ans;char cs[20][20];bool yes(int x,int y){       if(1<=x && x<=n && 1<=y && y<=m)    {        return true;    }                       return false;}inline int num(int x , int y , int xx = 0){       return (x-1)*16 + y + ac * xx;}int dx(int xx){    return (((xx-1) % ac + 1)-1) / 16 + 1;}int dy(int xx){       return (((xx-1) % ac + 1)-1) % 16 + 1;}int dn(int xx)              {    return (xx - 1) / ac + 1;       }void build(){    FF(i,maxn)    {        g[i].clear();    }       FOR(i,1,n) FOR(j,1,m)    {        if(cs[i][j]=='X')        {            zx.from = 0;                zx.to = num(i,j);            zx.id = g[zx.to].size();            zx.c =1;            g[0].pb ( zx );            swap(zx.from,zx.to);            zx.id = g[0].size() - 1;            zx.c = 0;            g[zx.from].pb(zx);        }    }        return ;}void add(int t){    int nowx,nowy;    int from,to;    FOR(k,t,t)    {        FOR(i,1,n) FOR(j,1,m)        {            if(cs[i][j] == '#')            {                continue;            }                from = num(i,j, 2*k - 2);            FF(e,5)                 {                nowx = i + dir[e][0];                nowy = j + dir[e][1];                if(!yes(nowx,nowy))                {                    continue;                }                to = num(nowx,nowy,2*k-1);                if(cs[nowx][nowy] != '#')                {                    zx.from =  from;                    zx.to = to;                    zx.c = 1;                    zx.id = g[to].size();                     g[from].pb(zx);                    swap(zx.from,zx.to);                    zx.c = 0;                    zx.id = g[from].size()-1;                    g[to].pb(zx);                    }                 }            from = num(i,j,2*k - 1);            to = num(i,j,2*k);            zx.from = from;            zx.to = to;            zx.id = g[to].size();            zx.c=1;            g[from].pb(zx);            swap(zx.from,zx.to);            zx.c = 0;            zx.id = g[from].size() - 1;            g[to].pb(zx);             if(cs[i][j] == '@')            {                zx.from = to;                zx.to = end;                zx.id = g[end].size();                zx.c = 1;                g[zx.from].pb(zx);                swap(zx.from,zx.to);                zx.c=0;                zx.id=g[to].size()-1;                g[zx.from].pb(zx);              }        }            }       }bool bfs0(){    CL(q);    MM(vis,false);    FOR(i,1,n) FOR(j,1,m)    {          if(cs[i][j]=='@')        {            q.push(num(i,j));            vis[i][j] = true;        }    }           int nowx,nowy,now;    while(!q.empty())    {        now = q.front();        q.pop();        FOR(i,1,4)        {            nowx = dx(now) + dir[i][0];            nowy = dy(now) + dir[i][1];            if(cs[nowx][nowy] != '#' && !vis[nowx][nowy] && yes(nowx,nowy))            {                   q.push(num(nowx,nowy));                vis[nowx][nowy] = true;            }        }    }    FOR(i,1,n) FOR(j,1,m)    {        if(cs[i][j] == 'X' && vis[i][j] == false)        {                                               return false;        }    }                        return true;  }                bool bfs(){      CL(q);    MM(cen,-1);    q.push(0);    cen[0]=0;    int now,to;    while(!q.empty())    {        now = q.front();        q.pop();        FF(i,g[now].size())         {            to = g[now][i].to;            if(g[now][i].c > 0 && cen[to] == -1)            {                   cen[to] = cen[now] + 1;                q.push(to);            }        }        }    return cen[end] != -1;}int dfs(int flow = inf , int now = 0){       if(now == end)      {           return flow;    }    int temp,sum=0;    int to;    FF(i,g[now].size())    {        to = g[now][i].to;        if(cen[to] == cen[now] + 1 && flow > sum && g[now][i].c >0 )        {            temp = dfs ( min ( g[now][i].c , flow - sum ) , to );            sum += temp;            g[now][i].c -= temp;            g[to][g[now][i].id].c += temp;        }    }    if(!sum) cen[now] = -1;    return sum;}bool dinic(){      while(bfs())    {        ans += dfs();    }         if(ans == total)    {        return true;    }                       return false;}int bin(){    ans=0;    if( !bfs0 () )    {           return -1;    }      build();       for(int tt=1;;tt++)    {        add(tt);        if(dinic())        {            return tt;        }    }    }int main(){    while(cin>>n>>m)    {           total = 0;        FOR(i,1,n) FOR(j,1,m)           {            cin>>cs[i][j];            if(cs[i][j]=='X')            {                total++;            }        }        cout<<bin()<<endl;    }    return 0;    }


原创粉丝点击