zoukankan      html  css  js  c++  java
  • POJ 1895 分层图网络流+输出路径

    题意:
    题目描述:在公元3141年人类的足迹已经遍布银河系。为了穿越那巨大的距离,人类发明了一种名为超时空轨道的技术。超时空轨道是双向的,连接两个星系,穿越轨道需要一天的时间。然而这个轨道只能同时给一艘飞船使用,也就是说,每条轨道每天只能有一艘飞船穿越。现在IBM公司要把K(K≤50)台超级计算机从地球运到Eisiem星系去,由于这些超级计算机个头巨大,一台计算机就要用一艘飞船来运。现在人类能够到达N(N≤50)个星系,拥有M(M≤200)条超时空轨道,太阳系的编号为S,Eisiem星系的编号为T。你需要求出至少需要几天才能将这些超级计算机全部运到目的地。注意,IBM公司是非常NB的公司,所有的超时空轨道都会优先给IBM公司使用。
    思路:
    这里写图片描述
    这里写图片描述
    From lydrainbowcat

    //By SiriusRen
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 5555
    #define M 444444
    int n,m,k,from[N],to[N],jy,rec[N][55],rect[N][55],inf=0x3f3f3f3f;
    int first[N],next[M],v[M],w[M],tot,T=5551,day,vis[N],ans;
    void Add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
    void add(int x,int y,int z){Add(x,y,z),Add(y,x,0);}
    bool tell(){
        memset(vis,-1,sizeof(vis)),vis[0]=0;
        queue<int>q;q.push(0);
        while(!q.empty()){
            int t=q.front();q.pop();
            for(int i=first[t];~i;i=next[i])
                if(w[i]&&vis[v[i]]==-1)
                    vis[v[i]]=vis[t]+1,q.push(v[i]);
        }return vis[T]!=-1;
    }
    int zeng(int x,int y){
        if(x==T)return y;
        int r=0;
        for(int i=first[x];~i&&y>r;i=next[i])
            if(w[i]&&vis[v[i]]==vis[x]+1){
                int t=zeng(v[i],min(y-r,w[i]));
                w[i]-=t,w[i^1]+=t,r+=t;
            }
        if(!r)vis[x]=-1;
        return r;
    }
    void dfs(int x,int Day){
        for(int i=first[x];~i;i=next[i])
            if(w[i^1]){
                w[i]++,w[i^1]--;
                if(v[i]==T)return;
                if(v[i]==x+n)dfs(v[i],Day+1);
                else{
                    rec[Day][0]++;
                    rec[Day][rec[Day][0]]=jy;
                    rect[Day][rec[Day][0]]=(v[i]-1)%n+1;
                    dfs(v[i],Day+1); 
                }
                break;
            }
    }
    int main(){
        memset(first,-1,sizeof(first));
        scanf("%d%d%d%d%d",&n,&m,&k,&from[0],&to[0]);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&from[i],&to[i]);
        }add(0,from[0],k);
        day=0;
        while(++day){
            for(int i=1;i<=m;i++)add(from[i]+(day-1)*n,to[i]+day*n,1),add(to[i]+(day-1)*n,from[i]+day*n,1);
            for(int i=1;i<=n;i++)add(i+(day-1)*n,i+day*n,inf);
            add(to[0]+day*n,T,inf);
            while(tell())while(jy=zeng(0,inf))ans+=jy;
            if(ans==k){printf("%d
    ",day);break;}
        }
        for(jy=k;jy;jy--)dfs(0,0);
        for(int i=1;i<=day;i++){
            printf("%d ",rec[i][0]);
            for(int j=1;j<=rec[i][0];j++)
                printf("%d %d ",rec[i][j],rect[i][j]);
            putchar('
    ');
        }
    }

    这里写图片描述

  • 相关阅读:
    cf C. Vasya and Robot
    zoj 3805 Machine
    cf B. Vasya and Public Transport
    cf D. Queue
    cf C. Find Maximum
    cf B. Two Heaps
    cf C. Jeff and Rounding
    cf B. Jeff and Periods
    cf A. Jeff and Digits
    I Think I Need a Houseboat
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532140.html
Copyright © 2011-2022 走看看