hdu 1733 Escape

拆点,假设 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;    
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
疫情居家办公系统管理系统按照操作主体分为管理员和用户。管理员的功能包括办公设备管理、部门信息管理、字典管理、公告信息管理、请假信息管理、签到信息管理、留言管理、外出报备管理、薪资管理、用户管理、公司资料管理、管理员管理。用户的功能等。该系统采用了MySQL数据库,Java语言,Spring Boot框架等技术进行编程实现。 疫情居家办公系统管理系统可以提高疫情居家办公系统信息管理问题的解决效率,优化疫情居家办公系统信息处理流程,保证疫情居家办公系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理疫情居家办公系统信息,包括外出报备管理,培训管理,签到管理,薪资管理等,可以管理公告。 外出报备管理界面,管理员在外出报备管理界面中可以对界面中显示,可以对外出报备信息的外出报备状态进行查看,可以添加新的外出报备信息等。签到管理界面,管理员在签到管理界面中查看签到种类信息,签到描述信息,新增签到信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值