zoukankan      html  css  js  c++  java
  • luogu P2756 飞行员配对方案问题

    二次联通门 : luogu P2756 飞行员配对方案问题

    /*
        luogu P2756 飞行员配对方案问题
        
        二分图匹配 
        
        输出时略麻烦 
        从源点开始
            若扫到的下一条边的流量为0
            则证明该条边可以
                再枚举当前点的边,记录答案
                最后输出即可 
    */
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    #define Max 202
    #define INF 1e7
    
    using namespace std;
    
    
    void read (int &now)
    {
        now = 0;
        char word = getchar ();
        while (word < '0' || word > '9')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
    }
    
    struct Edge
    {
        int to;
        int flow;
        int next;
    }edge[Max << 5];
    
    int Edge_Count = 1;
    int edge_list[Max];
    int N, M;
    int S = 0, T;
    
    inline void AddEdge (int from, int to)
    {
        Edge_Count++;    
        edge[Edge_Count].flow = 1;
        edge[Edge_Count].to = to;
        edge[Edge_Count].next = edge_list[from];
        edge_list[from] = Edge_Count;
        Edge_Count++;
        edge[Edge_Count].flow = 0;
        edge[Edge_Count].to = from;
        edge[Edge_Count].next = edge_list[to];
        edge_list[to] = Edge_Count;
    }
    
    int deep[Max];
    
    int Flowing (int now, int flow)
    {
        if (flow <= 0 || now == T)
            return flow;
        int pos, res = 0;
        for (int i = edge_list[now]; i; i = edge[i].next)
        {
            if (deep[edge[i].to] != deep[now] + 1 || edge[i].flow <= 0)
                continue;
            pos = Flowing (edge[i].to, min (edge[i].flow, flow));
            res += pos;
            flow -= pos;
            edge[i].flow -= pos;
            edge[i ^ 1].flow += pos;
            if (flow == 0)
                return res;
        }
        return res;
    }
    
    struct Link
    {
        int first;
        int second;
    }link[Max];
    
    int main (int argc, char *argv[])
    {
        read (M);
        read (N);
        T = N + 2;
        int x, y;
        while (scanf ("%d%d", &x, &y) && x != -1 && y != -1)
            AddEdge (x, y);
        for (int i = 1; i <= M; i++)
            AddEdge (S, i);
        for (int i = M + 1; i <= N; i++)
            AddEdge (i, T);
        int Answer = 0;
        while (true)
        {
            bool flag = false;
            memset (deep, -1, sizeof deep);
            queue <int> Queue;
            Queue.push (S);
            deep[S] = 0; 
            int now;
            while (!Queue.empty ())
            {
                now = Queue.front ();
                Queue.pop ();
                for (int i = edge_list[now]; i; i = edge[i].next)
                    if (deep[edge[i].to] < 0 && edge[i].flow)
                    {
                        deep[edge[i].to] = deep[now] + 1;
                        if (edge[i].to == T)
                        {
                            flag = true;
                            break;
                        }
                        Queue.push (edge[i].to); 
                    }
                if (flag)
                    break;
            }
            if (deep[T] < 0)
                break;
            Answer += Flowing (S, INF);
        }
        if (!Answer)
        {
            printf ("No Solution!");
            return 0;
        }
        printf ("%d
    ", Answer);
        int Count = 0;
        for (int i = edge_list[S]; i; i = edge[i].next)
            if (!edge[i].flow)
                for (int j = edge_list[edge[i].to]; j; j = edge[j].next)
                    if (!edge[j].flow)
                    {
                        if (edge[i].to == T || edge[j].to == S || edge[i].to == S || edge[j].to == T)
                            continue;
                        Count++;
                        link[Count].first = edge[i].to;
                        link[Count].second = edge[j].to;
                    }
        for (int i = 1; i <= Count; i++)
            printf ("%d %d
    ", link[i].first, link[i].second);
        return 0;
    }
  • 相关阅读:
    状态同步和帧同步
    SVN和Git的使用
    客户端知识点
    客户端性能优化
    H5游戏开发面试经验
    2.0 pomelo-treasure官方demo的使用
    1.0 pomelo环境的搭建和部署
    python 网络编程
    冒泡排序
    面向对象-反射和元类
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6882682.html
Copyright © 2011-2022 走看看