zoukankan      html  css  js  c++  java
  • P2754 [CTSC1999]家园

     枚举天数后分层建图,跑最大流,第一次达到最大流大于运输人数的天数就是答案。

    代码写得稀烂,溜了溜了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=10000+10;
    const int M=100000+100;
    const int INF=0x3f3f3f3f;
    int n,m,k,s,t,p[30];
    vector<int> V[30];
    struct edge{
        int nxt,to,cap;
    }edges[M<<1];
    int cnt=1,head[N],cur[N];
    
    void add_edge(int x,int y,int z) {
        edges[++cnt].nxt=head[x]; edges[cnt].to=y; edges[cnt].cap=z; head[x]=cnt;
    }
    
    int dep[N]; 
    queue<int> q;
    bool bfs() {
        while (!q.empty()) q.pop();
        memset(dep,0,sizeof(dep));
        dep[s]=1; q.push(s);
        while (!q.empty()) {
            int x=q.front(); q.pop();
            for (int i=head[x];i;i=edges[i].nxt) {
                edge e=edges[i];
                if (!dep[e.to] && e.cap) {
                    dep[e.to]=dep[x]+1;
                    q.push(e.to);
                }
            }
        }
        return dep[t];
    }
    
    int dfs(int x,int lim) {
        if (x==t) return lim;
        for (int& i=cur[x];i;i=edges[i].nxt) {
            edge e=edges[i];
            if (dep[x]+1==dep[e.to] && e.cap) {
                int flow=dfs(e.to,min(lim,e.cap));
                if (flow>0) {
                    edges[i].cap-=flow;
                    edges[i^1].cap=+flow;
                    return flow;  //找到一条增广路就要return 
                }
            }
        }
        return 0;
    }
    
    int Dinic() {
        int maxflow=0;
        while (bfs()) {
            for (int i=s;i<=t;i++) cur[i]=head[i];  //当前弧优化 
            while (int flow=dfs(s,INF)) maxflow+=flow;
        }
        return maxflow;
    }
    
    void build(int day) {
        cnt=1; memset(head,0,sizeof(head));
        s=0; t=n*day+1;
        for (int i=1;i<=m;i++) {
            int lst=0;
            for (int j=1;j<day;j++) {
                int now=lst+1;
                if (now>=V[i].size()) now=0;
                int u=V[i][lst],v=V[i][now];
                if (u==0) u=s; else if (u==-1) u=t; else u=(j-1)*n+u;
                if (v==0) v=s; else if (v==-1) v=t; else v=(j)*n+v;
                if (u!=t && v!=s) add_edge(u,v,p[i]),add_edge(v,u,0);
                lst=now;
            }
        }
        for (int j=0;j<day-1;j++)
            for (int i=1;i<=n;i++) {
                add_edge(j*n+i,(j+1)*n+i,INF);
                add_edge((j+1)*n+i,j*n+i,0);
            }
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for (int i=1;i<=m;i++) {
            int t; scanf("%d%d",&p[i],&t);
            for (int j=1;j<=t;j++) {
                int x; scanf("%d",&x);
                V[i].push_back(x);
            }
        }
        
        for (int i=1;i;i++) {
            build(i);
            int tmp=Dinic();
            if (tmp>=k) { printf("%d
    ",i-1); break; }
            if (i>=1000) { printf("%d",0); break; }
        }
        return 0;
    } 
  • 相关阅读:
    jvisualm 结合 visualGC 进行jvm监控,并分析垃圾回收
    linux 查看服务器cpu 与内存配置
    arthas 使用总结
    selinux contexts 安全上下文的临时更改
    Android 8.1 Doze模式分析(五) Doze白名单及Debug方式
    Window 任意窗口置顶软件Window TopMost Control
    Android ApkToolPlus一个可视化的跨平台 apk 分析工具
    SVN Please execute the 'Cleanup' command.
    Android 如何在64位安卓系统中使用32位SO库
    Android cmd命令查看apk是32位还是64位?
  • 原文地址:https://www.cnblogs.com/clno1/p/10726536.html
Copyright © 2011-2022 走看看