zoukankan      html  css  js  c++  java
  • ACdream 1017 [分层图][网络流]

    /*
    大连热身C题
    
    不要低头,不要放弃,不要气馁,不要慌张
    题意:
    给一个城市路线图,给定起点给定终点。有n个货物从起点运送到终点。城市的边是无向边。
    每个货物每天如果通过某条路,那么这天这条路只能运送这一个货物,另外一个方向也不得运送货物。
    问最少需要多少天,使得起点的货物全部运送到终点。
    
    思路:
    按照天数将城市节点裂点。即第i天的某个节点。
    枚举天数,不断重新构建网络,跑最大流。找到最小的天数使得最大流大于等于n。
    看了大神的博客,知道这个东西实际上叫做分层图。
    
    */
    
    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=10000,MAXM=100000,inf=1e9;
    struct Edge
    {
        int v,c,f,nx;
        Edge() {}
        Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
    } E[MAXM];
    int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],sz;
    void init()
    {
        sz=0; memset(G,-1,sizeof(G));
    }
    void add_edge(int u,int v,int c)
    {
        //printf("%d %d 
    ",u,v);
        E[sz]=Edge(v,c,0,G[u]); G[u]=sz++;
        E[sz]=Edge(u,0,0,G[v]); G[v]=sz++;
    }
    bool bfs(int S,int T)
    {
        static int Q[MAXN]; memset(dis,-1,sizeof(dis));
        dis[S]=0; Q[0]=S;
        for (int h=0,t=1,u,v,it;h<t;++h)
        {
            for (u=Q[h],it=G[u];~it;it=E[it].nx)
            {
                if (dis[v=E[it].v]==-1&&E[it].c>E[it].f)
                {
                    dis[v]=dis[u]+1; Q[t++]=v;
                }
            }
        }
        return dis[T]!=-1;
    }
    int dfs(int u,int T,int low)
    {
        if (u==T) return low;
        int ret=0,tmp,v;
        for (int &it=cur[u];~it&&ret<low;it=E[it].nx)
        {
            if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f)
            {
                if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
                {
                    ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp;
                }
            }
        }
        if (!ret) dis[u]=-1; return ret;
    }
    int dinic(int S,int T)
    {
        int maxflow=0,tmp;
        while (bfs(S,T))
        {
            memcpy(cur,G,sizeof(G));
            while (tmp=dfs(S,T,inf)) maxflow+=tmp;
        }
        return maxflow;
    }
    struct edge{
        int id;
        edge *next;
    };
    edge edges[1000];
    edge *adj[500];
    int ednum;
    inline void addedge(int a,int b){
        edge *tmp=&edges[ednum++];
        tmp->id=b;
        tmp->next=adj[a];
        adj[a]=tmp;
    }
    int x[1000],y[1000];
    int ddis[500];
    struct st{
        st(){}
        st(int a,int b){
            id=a;step=b;
        }
        int id,step;
    };
    int main()
    {
        int n,m,k,s,t;
        while(scanf("%d%d%d%d%d",&n,&m,&k,&s,&t)!=EOF){
            if(m>=100)while(1)puts("+++");
            ednum=0;
            memset(adj,NULL,sizeof(adj));
            for(int i=1;i<=m;i++){
                scanf("%d%d",x+i,y+i);
                addedge(x[i],y[i]);
                addedge(y[i],x[i]);
            }
            memset(ddis,-1,sizeof(ddis));
            for(int i=1;;i++){
                init();
                for(int j=1;j<=m;j++){
                    for(int tt=0;tt<i;tt++){
                        add_edge(tt*n+x[j],tt*n+n+y[j],1);
                        add_edge(tt*n+y[j],tt*n+n+x[j],1);
                    }
                }
                add_edge(5000,5002,k);
                for(int j=0;j<=i;j++){
                    add_edge(j*n+t,5001,inf);
                    add_edge(5002,j*n+s,inf);
                }
                int w=dinic(5000,5001);
                if(w>=k){
                    printf("%d
    ",i);
                    break;
                }
            }
        }
    }
  • 相关阅读:
    springboot项目启动成功后执行一段代码的两种方式
    ELK相关资料整理
    Golang指针解析
    Golang文件操作
    Go Channel介绍
    Go语言new和make的区别
    SpringBoot+AOP实现记录操作日志和异常日志,并保存到数据库
    【面试专栏】Java 阻塞队列
    Linux安装Jenkins并构建SpringBoot工程
    Linux安装git
  • 原文地址:https://www.cnblogs.com/tun117/p/6002017.html
Copyright © 2011-2022 走看看