zoukankan      html  css  js  c++  java
  • la 2957 uva 1324 Dinic 最大流

    y the year 3141, the human civilization has spread all over the galaxy. The special hypertunnels are used to travel from one star system to another. To use the hypertunnel, you fly to a special location near the source star using your spaceship, activate the hyperjumper, fly through the hypertunnel, get out near your destination star and fly to the planet you need. The whole process takes exactly one day. A small drawback of the system is that for each tunnel every day only one spaceship can travel using this tunnel.

    You are working in the transportation department of the ``Intergalaxy Business Machines" company. This morning your boss has assigned a new task to you. To run the programming contest IBM needs to deliver K supercomputers from Earth where the company headquarters are located to the planet Eisiem. Since supercomputers are very large, one needs the whole spaceship to carry each supercomputer. You are asked to find a plan to deliver the supercomputers that takes as few days as possible. Since IBM is a very powerful corporation, you may assume that any time you need some tunnel for hyperjump, it is at your service. However, you still can use each tunnel only once a day.

    Input 

    Input consists of several datasets. The first line of each dataset contains N - the number of star systems in the galaxy, M - the number of tunnels, K - the number of supercomputers to be delivered, S - the number of the solar system (the system where planet Earth is) and T - the number of the star system where planet Eisiem is (2$ le$N$ le$50, 1$ le$M$ le$200, 1$ le$K$ le$50, 1$ le$S, T$ le$N, S $ 
eq$ T).

    Next M lines contain two different integer numbers each and describe tunnels. For each tunnel the numbers of star systems that it connects are given. The tunnel can be traveled in both directions, but remember that each day only one ship can travel through it, in particular, two ships cannot simultaneously travel through the same tunnel in opposite directions. No tunnel connects a star to itself and any two stars are connected by at most one tunnel.

    Output 

    On the first line of the output for each dataset print L - the fewest number of days needed to deliver K supercomputers from star system S to star system T using hypertunnels. Next L lines must describe the process. Each line must start with Ci - the number of ships that travel from one system to another this day. Ci pairs of integer numbers must follow, pair A, B means that the ship number A travels from its current star system to star system B.

    It is guaranteed that there is a way to travel from star system S to star system T.

    Sample Input 

    6 7 4 1 6
    1 2
    2 3
    3 5
    5 6
    1 4
    4 6
    4 3
    

    Sample Output 

    4
    2 1 2 2 4
    3 1 3 2 6 3 4
    3 1 5 3 6 4 4
    2 1 6 4 6
    

    抄白书,把时间拆了,同一星球第i-1天到第i天连一条弧,对不同的星球且有弧的也是连一条第i-1天到第i天的弧,然后从一天开始在原来得到的最大流基础上逐渐加天数,最后可得姐:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    
    using namespace std;
    
    #define LL long long
    #define ULL unsigned long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define MAX_LL 0x7fffffffffffffff
    #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    
    #define MAXN 5555
    #define MAXM 222
    #define MAXNM 100000
    #define INF 1000000000
    
    struct edge{
        int u, v, cap, flow, nxt;
    }e[MAXNM];
    int cc, h[MAXN];
    
    void add(int u, int v, int cap){
        e[cc]=(edge){u, v, cap, 0, h[u]};
        h[u]=cc++;
        e[cc]=(edge){v, u, 0, 0, h[v]};
        h[v]=cc++;
    }
    
    int vis[MAXN], d[MAXN];
    bool bfs(int s, int t){
        queue<int> q;
        memset(vis, 0, sizeof(vis));
        d[s]=0;     vis[s]=true;
        q.push(s);
        while(!q.empty()){
            int u=q.front();    q.pop();
            for(int i=h[u]; i!=-1; i=e[i].nxt){
                int v=e[i].v, cap=e[i].cap, flow=e[i].flow;
                if(!vis[v] && cap>flow){
                    vis[v]=true;
                    d[v]=d[u]+1;
                    q.push(v);
                }
            }
        }
        return vis[t];
    }
    
    int cur[MAXN];
    int dfs(int u, int a, int t){
        if(u==t || a==0) return a;
        int flow=0, f;
        for(int &i=cur[u]; i!=-1; i=e[i].nxt){
            int v=e[i].v, &ef=e[i].flow, cap=e[i].cap;
            if(d[v]==d[u]+1 && (f=dfs(v, MIN(a, cap-ef), t))>0){
                a-=f;
                flow+=f;
                ef+=f;
                e[i^1].flow-=f;
                if(a==0) break;                 //this is a improvement
            }
        }
        return flow;
    }
    
    int Dinic(int s, int t, int n, int need){
        int flow=0, i;
        while(bfs(s, t)){
            for(i=0; i<n; i++) cur[i]=h[i];
            flow+=dfs(s, need-flow, t);
            if(flow==need) return flow;
        }
        return flow;
    }
    
    int main(){
    //    freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
    //    freopen("C:\Users\Administrator\Desktop\out1.txt","w",stdout);
        int n, m, k, S, T;
        int u[MAXM], v[MAXM];
        while(scanf(" %d %d %d %d %d", &n, &m, &k, &S, &T)==5){
            int i, j;
            for(i=0; i<m; i++) scanf(" %d %d", &u[i], &v[i]);
    //        g.init();
            memset(h, -1, sizeof(h));       cc=0;
            int day=1;
    //        g.clearNode(0, n-1);
            int flow=0;
            while(true){
    //          g.clearNode(day*n, day*n+n-1);
                for(i=0; i<n; i++) /*g.AddEdge((day-1)*n+i, day*n+i, INF); */ add((day-1)*n+i, day*n+i, INF);
                for(i=0; i<m; i++){  /*
                    g.AddEdge((day-1)*n+u[i]-1, day*n+v[i]-1);
                    g.AddEdge((day-1)*n+v[i]-1, day*n+u[i]-1);   */
                    add((day-1)*n+u[i]-1, day*n+v[i]-1, 1);
                    add((day-1)*n+v[i]-1, day*n+u[i]-1, 1);
                }
    //            flow+=g.Maxflow(S-1, day*n+T-1, k-flow);
                flow+=Dinic(S-1, day*n+T-1, day*n+n, k-flow);
                if(flow==k) break;
                day++;
            }
            printf("%d
    ", day);
            int idx=0;
            vector<int> location(k, S);
            for(int d=1; d<=day; d++){
                idx+=n*2;
                vector<int> moved(k, 0);
                vector<int> a, b;
                for(i=0; i<m; i++){
                    int f1=e[idx].flow;     idx+=2;
                    int f2=e[idx].flow;     idx+=2;
                    if(f1==1 && f2==0) {a.push_back(u[i]); b.push_back(v[i]);}
                    if(f2==1 && f1==0) {a.push_back(v[i]); b.push_back(u[i]);}
                }
                printf("%d", a.size());
                for(i=0; i<a.size(); i++){
                    for(j=0; j<k; j++) if(!moved[j] && location[j]==a[i]){
                        moved[j]=1;
                        printf(" %d %d", j+1, b[i]);
                        location[j]=b[i];
                        break;
                    }
                }
                printf("
    ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    ModuleNotFoundError: No module named 'babel' 解决办法
    linux修改时间
    Ubuntu 18.04 安装 odoo12 源码版
    开源ERP框架Odoo学习
    浅谈我对DDD领域驱动设计的理解(转)
    一步步带你做vue后台管理框架
    一步一步使用ABP框架搭建正式项目系列教程
    C#编写好的windows服务,在本机上运行很好,考到其他电脑运行出现“错误1053: 服务没有及时响应启动或控制请求”的解决办法
    公用表表达示展BOM示例
    sqlserver 2005新功能
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3330151.html
Copyright © 2011-2022 走看看