zoukankan      html  css  js  c++  java
  • 最大流(多个源点,多个汇点) 之 poj 1274

    //  [5/28/2014 Sjm]
    /*
    最大流:多个源点,多个汇点
    // 若按二分图匹配做,请参见:http://www.cnblogs.com/shijianming/p/4140846.html
     
    思路:
    1)增加一个超级源点 S,从 S 向 每个源点 连一条容量为对应最大流出流量的边
    2)增加一个超级汇点 T,从 每一个汇点 向 T 连一条容量为对应最大流入容量的边
     
    对于此题:
    源点 cows (范围:M+1 ~ M+N),汇点 stalls (范围:1 ~ M)
    设 cows 与 the stalls (in which that cow is willing to produce milk)之间的容量为 1
    1)设 0 为超级源点,
       因为每个 cow 流出的最大流出流量为 1(只能连一个stall),所以得:超级源点 向每个 cows 的连线的流量为 1
    2)设 M+N+1 为超级汇点
       因为流入每个 stall 最大流量为 1(只能被一个cow连接),所以得:每个 stall 向 超级汇点 的连线的连线的流量为 1
     
    */
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <vector>
     5 #include <algorithm>
     6 using namespace std;
     7 const int MAX_V = 410;
     8 const int INF = 0x3f3f3f3f;
     9 int N, M;
    10 
    11 struct edge { int to, cap, rev; };
    12 vector<edge> G[MAX_V];
    13 bool used[MAX_V];
    14 
    15 void add_edge(int from, int to, int cap)
    16 {
    17     edge e1 = { to, cap, G[to].size() };
    18     G[from].push_back(e1);
    19     edge e2 = { from, 0, G[from].size() - 1 };
    20     G[to].push_back(e2);
    21 }
    22 
    23 int dfs(int v, int t, int f)
    24 {
    25     if (v == t) return f;
    26     used[v] = true;
    27     for (int i = 0; i < G[v].size(); i++) {
    28         edge &e = G[v][i];
    29         if (!used[e.to] && (e.cap > 0)) {
    30             int d = dfs(e.to, t, min(f, e.cap));
    31             if (d > 0) {
    32                 e.cap -= d;
    33                 G[e.to][e.rev].cap += d;
    34                 return d;
    35             }
    36         }
    37     }
    38     return 0;
    39 }
    40 
    41 int Solve(int s, int t)
    42 {
    43     int flow = 0;
    44     for (;;)
    45     {
    46         memset(used, 0, sizeof(used));
    47         int f = dfs(s, t, INF);
    48         if (!f) return flow;
    49         flow += f;
    50     }
    51 }
    52 
    53 int main()
    54 {
    55     //freopen("input.txt", "r", stdin);
    56     //freopen("output.txt", "w", stdout);
    57     while (~scanf("%d %d", &N, &M))
    58     {
    59         for (int i = 1; i <= N; i++) {
    60             int mycount;
    61             scanf("%d", &mycount);
    62             int tep;
    63             for (int j = 0; j < mycount; j++) {
    64                 scanf("%d", &tep);
    65                 add_edge(M + i, tep, 1);
    66             }
    67         }
    68         for (int i = 1; i <= N; i++) {
    69             add_edge(0, M+i, 1);
    70         }
    71         for (int i = 1; i <= M; i++) {
    72             add_edge(i, M + N + 1, 1);
    73         }
    74         printf("%d
    ", Solve(0, M + N + 1));
    75         for (int i = 0; i < MAX_V; i++) {
    76             G[i].clear();
    77         }
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    每日日报
    每日日报
    flink入门到实战(2)flink优化总结
    flink入门到实战(1)入门学习
    机器学习算法一般步骤
    hadoop入门到实战(1)hive优化总结
    划重点|iOS15正式发布, 全新的通知推送系统,你必须要知道!
    云知声 Atlas 超算平台: 基于 Fluid + Alluxio 的计算加速实践
    终端卡顿优化的全记录
    云湖共生释放企业数据价值
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140847.html
Copyright © 2011-2022 走看看