zoukankan      html  css  js  c++  java
  • hdu 2063 过山车(二分图最佳匹配)

      经典的二分图最大匹配问题,因为匈牙利算法我还没有认真去看过,想先试试下网络流的做法,即对所有女生增加一个超级源,对所有男生增加一个超级汇,然后按照题意的匹配由女生向男生连一条边,跑一个最大流就是答案(以上所有边容量均为 1 ),我是直接上 Dinic 算法的模板的:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<vector>
      4 #include<queue>
      5 #include<algorithm>
      6 using namespace std;
      7 #define  sd(x)  scanf("%d",&(x))
      8 const int inf = 0x3fffffff;
      9 
     10 struct Edge {
     11     int from, to, cap, flow;
     12     Edge() {}
     13     Edge(int from, int to, int cap, int flow):
     14         from(from), to(to), cap(cap), flow(flow) {}
     15 };
     16 
     17 const int N = 1003;
     18 
     19 struct Dinic {
     20     int s,t;
     21     vector<Edge> edges;
     22     vector<int> G[N];
     23     bool vis[N];
     24     int d[N];
     25     int cur[N];
     26 
     27     void clear() {
     28         edges.clear();
     29         for(int i = 0; i < N; ++i)
     30             G[i].clear();
     31     }
     32     void addEdge(int from, int to, int cap) {
     33         edges.push_back(Edge(from, to, cap, 0));
     34         edges.push_back(Edge(to, from, 0, 0));
     35         int m = edges.size();
     36         G[from].push_back(m - 2);
     37         G[to].push_back(m - 1);
     38     }
     39     bool bfs() {
     40         memset(vis,0,sizeof(vis));
     41         queue<int> q;
     42         q.push(s);
     43         d[s] = 0;
     44         vis[s] = 1;
     45         while(!q.empty()) {
     46             int x = q.front();  q.pop();
     47             int len = G[x].size();
     48             for(int i = 0; i < len; ++i) {
     49                 Edge &e = edges[G[x][i]];
     50                 if(!vis[e.to] && e.cap > e.flow) {
     51                     d[e.to] = d[x] + 1;
     52                     vis[e.to] = 1;
     53                     q.push(e.to);
     54                 }
     55             }
     56         }
     57         return vis[t];
     58     }
     59     int dfsAll(int x, int a) {
     60         if(x == t || a == 0)    return a;
     61         int flow = 0, f, len = G[x].size();
     62         for(int &i = cur[x]; i < len; ++i) {
     63             Edge &e = edges[G[x][i]];
     64             if(d[e.to] == d[x] + 1 && (f = dfsAll(e.to, min(a, e.cap - e.flow)) > 0)) {
     65                 e.flow += f;
     66                 edges[G[x][i]^ 1].flow -= f;
     67                 flow += f;
     68                 a -= f;
     69                 if(a == 0)  break;
     70             }
     71         }
     72         return flow;
     73     }
     74     int Maxflow(int s, int t) {
     75         this->s = s;
     76         this->t = t;
     77         int flow = 0;
     78         while(bfs()) {
     79             memset(cur, 0, sizeof(cur));
     80             flow += dfsAll(s,inf);
     81         }
     82         return flow;
     83     }
     84 } dinic;
     85 
     86 int c[1003];
     87 
     88 #define sd2(x,y)  scanf("%d%d",&(x),&(y))
     89 #define sd3(x,y,z)  scanf("%d%d%d",&(x),&(y),&(z))
     90 
     91 int main() {
     92     int n,m,k,x,y;
     93     while(~sd3(k, m, n), k) {
     94         dinic.clear();
     95         while(k--) {
     96             sd2(x,y);
     97             y += m;
     98             dinic.addEdge(x, y, 1);
     99 //            dinic.addEdge(y, x, 1);
    100         }
    101         for(int i = 1; i <= m; ++i)
    102             dinic.addEdge(0, i, 1);
    103         for(int i = m + 1; i <= m + n; ++i)
    104             dinic.addEdge(i, m + n + 1, 1);
    105         printf("%d
    ",dinic.Maxflow(0, m + n + 1));
    106     }
    107     return 0;
    108 }
    最大流实现最佳匹配

      需要注意的是男女生的编号,还有女生指向男生的是有向边,不需要两次的 addEdge。wa 了两次才找出所有问题。。。

     

  • 相关阅读:
    [dev][ipsec][esp] ipsec链路中断的感知问题
    [dev] Go语言查看doc与生成API doc
    [daily]gtk程序不跟随系统的dark主题
    [dev] Go的协程切换问题
    基因程序设计/基因编程/遗传编程
    [daily][emacs][go] 配置emacs go-mode的编辑环境以及环境变量问题
    Java Spring中@Query中使用JPQL LIKE 写法
    JavaScript 使用HTML DOM的oninput事件,实时监听value值变化
    Java中执行.exe文件
    Java关于List<String> 进行排序,重写Comparator()方法
  • 原文地址:https://www.cnblogs.com/Newdawn/p/4674683.html
Copyright © 2011-2022 走看看