codevs 1422 河城荷取

二次联通门 : codevs 1422 河城荷取

 

 

 

 

/*
    codevs 1422 河城荷取
    
    二分费用
    
    重新构图
    最大流判断是否可行
    
    用了邻接矩阵来存初始的流量和费用。。。
    慢的要死
     
*/
#include <cstring>
#include <cstdio>
#include <queue>

#define Max 2003
#define INF 1e9

void read (int &now)
{
    register char word = getchar ();
    for (now = 0; word < '0' || word > '9'; word = getchar ());
    for (; word >= '0' && word <= '9'; now = now * 10 + word - '0', word = getchar ());
}


int N, M, L, K;

int can_flow[Max][Max];
int cost[Max][Max];

inline int max (int &a, int &b)
{
    return a > b ? a : b;
}

inline int min (int &a, int &b)
{
    return a < b ? a : b;
}
int T;
const int S = 0;

class Net_Flow_Type
{
        
    private :
        
        int __to[Max * Max], __next[Max * Max];
        int __flow[Max * Max];
        
        int Edge_Count;
        int edge_list[Max];
        int deep[Max];
        
        int __tech_[Max];
        
    public :
                
        inline void Clear ()
        {
            Edge_Count = 1;
            memset (edge_list, 0, sizeof edge_list);
        }
        
        inline void Insert_edge (int from, int to, int key)
        {
            Edge_Count ++;
            __to[Edge_Count] = to;
            __next[Edge_Count] = edge_list[from];
            edge_list[from] = Edge_Count;
            __flow[Edge_Count] = key;
            
            Edge_Count ++;
            __to[Edge_Count] = from;
            __next[Edge_Count] = edge_list[to];
            edge_list[to] = Edge_Count;
            __flow[Edge_Count] = 0;
        }
        
        bool Bfs ()
        {
            std :: queue <int> Queue;
            memset (deep, -1, sizeof deep);
            deep[S] = 0;
            register int now;
            for (Queue.push (S); !Queue.empty (); Queue.pop ())
            {
                now = Queue.front ();
                register int i;
                for (i = edge_list[now]; i; i = __next[i])
                    if (deep[__to[i]] < 0 && __flow[i])
                    {
                        deep[__to[i]] = deep[now] + 1;
                        if (__to[i] == T)
                            return true;
                        Queue.push (__to[i]); 
                    }
            }
            return deep[T] != -1;
        }
        
        int Flowing (int now, int flow)
        {
            if (now == T || flow == 0)
                return flow;
            int res, last = 0;
            
            for (int &i = __tech_[now]; i; i = __next[i])
            {
                if (deep[__to[i]] != deep[now] + 1 || __flow[i] == 0)
                    continue;
                res = Flowing (__to[i], min (flow, __flow[i]));
                if (res > 0)
                {
                    last += res;
                    flow -= res;
                    __flow[i] -= res;
                    __flow[i ^ 1] += res;
                    if (flow == 0)
                        return last;
                }
            }
            if (flow != last)
                deep[now] = -1;
            return last;
        }
        
        int Dinic ()
        {
            int Answer = 0;
            while (Bfs ())
            {
                memcpy ( __tech_,edge_list, sizeof edge_list);
                Answer += Flowing (S, INF);
            }
            return Answer;
        }
};

Net_Flow_Type Flow;

bool Judge (int key)
{
    Flow.Clear ();
    for (register int i = 1; i <= L; i ++)
        Flow.Insert_edge (S, i, INF);
        
    for (register int i = 1, j; i <= N; i ++)
        for (j = 1; j <= N; j ++)
        {
            if (i == j)
                continue;
            if (cost[i][j] <= key)
                Flow.Insert_edge (i, j, can_flow[i][j]);
        }
    
    Flow.Insert_edge (N, T, INF);
    
    return Flow.Dinic () >= K;
}

int Answer;

int main (int argc, char *argv[])
{
    read (N);
    read (M);
    read (L);
    read (K);
    
    T = N + 1;
    int l = 0, r = -INF, Mid;
    
    memset (cost, 0x3f, sizeof cost);
    int x, y, z, s;
    for (register int i = 1; i <= M; i ++)
    {
        read (x);
        read (y);
        read (z);
        read (s);
        
        can_flow[x][y] = z;
        cost[x][y] = s;
        r = max (r, s);
    }
    
    for (; l <= r; )
    {
        Mid = l + r >> 1;
        if (Judge (Mid))
        {
            r = Mid - 1;
            Answer = Mid;
        }
        else
            l = Mid + 1;
    }
    
    printf ("%d", Answer);
    return 0;
}

 

posted @ 2017-07-20 09:41  ZlycerQan  阅读(322)  评论(0编辑  收藏  举报