• [CTSC1999]家园


    题意简化

    给定几趟循环移动的载客列车与站点数量,求所有人从第1站到最后一站的时间

    题目链接

    题解

    这个题一开始确实比较难想,因为这题数据规模奇小,我们可以直接根据每一单位时间建图。

    也就是说,第一步先建立虚拟原点汇点之后,将地球和月亮与其连边,然后每一天的每一趟车所在点向它下一天的所在点连一条容量为载客量的边,然后要把每一天的每个点向下一天连一条容量为inf的边(因为可以等嘛)

    然后就是裸的最大流了,dinic,EK都行

    代码

    
    #include<bits/stdc++.h>
    using namespace std;
    #define re register
    #define in inline
    #define ll long long
    #define get getchar()
    in int read()
    {
        int t=0,x=1; char ch=get;
        while((ch<'0' || ch>'9') && ch!='-') ch=get;
        if(ch=='-') ch=get,x=-1;
        while(ch<='9' && ch>='0') t=t*10+ch-'0',ch=get;
        return t*x;
    }
    const int inf=0x3f3f3f3f;
    const int _=60001;
    const int MAXN=55;
    struct edge{
        int to,ne,w;
    }e[_<<2];
    int tot=-1,S=50000,T=50001,head[_],h[MAXN],cyc[MAXN][MAXN],r[MAXN],n,m,k,dep[_],vis[_];
    in void add(int x,int y,int z)
    {
        e[++tot].ne=head[x],e[tot].to=y,e[tot].w=z,head[x]=tot;
        e[++tot].ne=head[y],e[tot].to=x,e[tot].w=0,head[y]=tot;
    }
    in bool bfs()
    {
        memset(dep,0x3f,sizeof(dep));
        memset(vis,0,sizeof(vis));
        queue<int >q;
        q.push(S);
        dep[S]=0;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(re int i=head[u];i!=-1;i=e[i].ne)
            {
                int v=e[i].to;
                if(e[i].w && dep[v]>dep[u]+1)
                {
                    dep[v]=dep[u]+1;
                    if(!vis[v]) {
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return dep[T]!=0x3f3f3f3f;
        
    }
    in int dfs(int u,int flow)
    {
        int rlow=0;
        if(u==T)
            return flow;
        int used=0;
        for(re int i=head[u];i!=-1;i=e[i].ne)
        {
            int v=e[i].to;
            if(e[i].w&&dep[v]==dep[u]+1) {
                if(rlow=dfs(v,min(flow-used,e[i].w)))
                {
                    used+=rlow;
                    e[i].w-=rlow;
                    e[i^1].w+=rlow;
                    if(rlow==flow) break;
                }
            }
        }
        return used;
    }
    in int dinic()
    {
        int ans=0;
        while(bfs())
           ans+=dfs(S,inf);
        return ans;
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read(),m=read(),k=read();
        n+=2;
        for(re int i=1;i<=m;i++) {
            h[i]=read();
            r[i]=read();
            for(re int j=0;j<r[i];j++) {
                cyc[i][j]=read()+2;
            }
        }
        int Time=0,sum=0;
        while(Time<=500)
        {
            add(S,Time*n+2,inf);
            add(Time*n+1,T,inf);
            if(Time!=0){
            for(re int i=1;i<=m;i++)
            {
                int x=cyc[i][(Time-1)%r[i]],y=cyc[i][((Time)%r[i])];
                add(x+(Time-1)*n,y+(Time)*n,h[i]);
            }
            for(re int i=1;i<=n;i++) add(i+(Time-1)*n,i+(Time)*n,inf);
            }
            sum+=dinic();
            if(sum>=k) {cout<<Time<<endl;return 0;}
            Time++;
        }
        printf("0
    ");
        return 0;
    }
    
    
  • 相关阅读:
    MySQL命令行基本操作
    MYSQL多表查询笔记
    MYSQL事务笔记
    Linux测试环境部署相关命令和步骤
    Jmeter录制脚本
    办公软件通讯录排序相关测试点
    Burp Suite抓包App
    安全测试 Burp Suite抓包工具
    及时通信办公软件,验证码登录,获取验证码失败原因分析和规避方法
    redis内存溢出问题分析和后续规避方法
  • 原文地址:https://www.cnblogs.com/yzhx/p/12209667.html
走看看 - 开发者的网上家园