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;
    }
  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6882682.html
Copyright © 2011-2022 走看看