zoukankan      html  css  js  c++  java
  • [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;
    }
    
    
  • 相关阅读:
    个人项目实战
    准备
    结队项目-第一次作业
    第三次作业--团队展示
    软件工程实践第二次作业
    软件工程实践第一次作业
    circle
    calculator
    视频课程学习及学习计划
    1001.A+B Format (20)
  • 原文地址:https://www.cnblogs.com/yzhx/p/12209667.html
Copyright © 2011-2022 走看看