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

    传送门

    这道题明显是二分图匹配……(因为我至今不会写匈牙利我就跑了遍dinic)

    非常的明显,自己设定一个原点和汇点。把原点向所有的外籍飞行员连容量为1的边,所有的英国飞行员向汇点连容量为1的边,中间的边按题目描述,给你一条你就建一条容量为1的边。

    之后直接跑网络流。至于最后怎么判断哪几个飞行员是配对的,直接判断那些连在中间的边,如果其反向边的流量不为0就说明这条边上面有流量,也就说明它被跑过。

    反正这题有spj可以直接过。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    const int M = 100005;
    const int INF = 1e9;
    typedef long long ll;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            ans *= 10;
            ans += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    struct edge
    {
        int next,to,v,from;
    }e[M];
    
    int m,n,head[M],ecnt = -1,deep[M],maxflow,x,y,source,sink,sum,cur[M];
    queue <int> q;
    
    void add(int x,int y,int z)
    {
        e[++ecnt].to = y;
        e[ecnt].v = z;
        e[ecnt].from = x;
        e[ecnt].next = head[x];
        head[x] = ecnt;
    }
    
    bool bfs(int s,int t)
    {
        memset(deep,-1,sizeof(deep));
        while(!q.empty()) q.pop();
        rep(i,0,n+1) cur[i] = head[i];
        deep[s] = 0,q.push(s);
        while(!q.empty())
        {
            int k = q.front();q.pop();
            for(int i = head[k];i != -1;i = e[i].next)
            {
                if(deep[e[i].to] == -1 && e[i].v)
                deep[e[i].to] = deep[k] + 1,q.push(e[i].to);
            }
        }
        if(deep[t] == -1) return 0;
        else return 1;
    }
    
    int dfs(int s,int t,int limit)
    {
        if(!limit || s == t) return limit;
        int flow = 0;
        for(int i = cur[s];i != -1;i = e[i].next)
        {
            cur[s] = i;
            if(deep[e[i].to] != deep[s] + 1) continue;
            int f = dfs(e[i].to,t,min(limit,e[i].v));
            if(f)
            {
                e[i].v -= f,e[i^1].v += f;
                limit -= f,flow += f;
                if(!limit) break;
            }
        }
        if(!flow) deep[s] = -2333333; 
        return flow;
    }
    
    void dinic(int s,int t)
    {
        while(bfs(s,t)) maxflow += dfs(s,t,INF);
    }
    
    int main()
    {
        memset(head,-1,sizeof(head));
        m = read(),n = read();
        source = 0,sink = n+1;
        while(1)
        {
            x = read(),y = read();
            if(x == -1 && y == -1) break;
            add(x,y,1),add(y,x,0),sum++;
        }
        rep(i,1,m) add(source,i,1),add(i,source,0);
        rep(i,m+1,n) add(i,sink,1),add(sink,i,0);
        dinic(source,sink);
        if(maxflow)
        {
            printf("%d
    ",maxflow);
            for(int i = 0;i <= (sum-1)<<1;i += 2)
            if(e[i^1].v != 0) printf("%d %d
    ",e[i].from,e[i].to);
        }
        else printf("No Solution!
    ");
        return 0;
    }
  • 相关阅读:
    20165311《网络对抗技术》Exp1 PC平台逆向破解
    20165311 《网络对抗技术》 Kali安装
    2018-2019-1 20165307 20165327 20165332 实验五 通讯协议设计
    2018-2019-1 20165307 20165327 20165332 实验四 外设驱动程序设计
    2018-2019-1 20165307 20165327 20165332 实验三 并发程序
    2018-2019-1 20165307 20165327 20165332 实验二 固件程序设计
    2018-2019-1 20165307 20165327 20165332 实验一 开发环境的熟悉
    2018-2019-1 20165307 《信息安全系统设计基础》第4周学习总结
    2018-2019-1 20165307 《信息安全系统设计基础》第3周学习总结
    20165307 《信息安全系统设计基础》 第一周
  • 原文地址:https://www.cnblogs.com/captain1/p/9557432.html
Copyright © 2011-2022 走看看