zoukankan      html  css  js  c++  java
  • zoj 3642 Just Another Information Sharing Problem【最大流||多重匹配】

    大意:

    有n个熊孩子,,每个熊孩子有a个秘密,他最少愿意分享b个秘密, 最多愿意分享c个秘密, 接下来a个数表示这个熊孩子有的a个秘密的id

    最后给一个熊孩子的编号m, 询问编号m最多能够知道多少个秘密

    分析:

    最大流, 但是询问的那个孩子的秘密就不用封印了,哈哈

    也可以用二分图多重匹配, 而且时间快了一倍

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <queue>
      6 #include <map>
      7 using namespace std;
      8 
      9 const int maxn = 500 * 250 + 10;
     10 const int INF = 1000000000;
     11 
     12 struct Edge {
     13     int from, to, cap, flow;
     14 };
     15 
     16 struct Dinic {
     17     int n, m, s, t;
     18     vector<Edge> edges;
     19     vector<int>G[maxn];
     20     bool vis[maxn];
     21     int d[maxn];
     22     int cur[maxn];
     23 
     24     void ClearAll(int n) {
     25         for(int i = 0; i <= n; i++) {
     26             G[i].clear();
     27         }
     28         edges.clear();
     29     }
     30 
     31     void AddEdge(int from, int to, int cap) {
     32         edges.push_back((Edge) { from, to, cap, 0 } );
     33         edges.push_back((Edge) { to, from, 0, 0 } );
     34         m = edges.size();
     35         G[from].push_back(m - 2);
     36         G[to].push_back(m - 1);
     37     }
     38 
     39     bool BFS()
     40     {
     41         memset(vis, 0, sizeof(vis) );
     42         queue<int> Q;
     43         Q.push(s);
     44         vis[s] = 1;
     45         d[s] = 0;
     46         while(!Q.empty() ){
     47             int x = Q.front(); Q.pop();
     48             for(int i = 0; i < G[x].size(); i++) {
     49                 Edge& e = edges[G[x][i]];
     50                 if(!vis[e.to] && e.cap > e.flow) {
     51                     vis[e.to] = 1;
     52                     d[e.to] = d[x] + 1;
     53                     Q.push(e.to);
     54                 }
     55             }
     56         }
     57         return vis[t];
     58     }
     59 
     60     int DFS(int x, int a) {
     61         if(x == t || a == 0) return a;
     62         int flow = 0, f;
     63         for(int& i = cur[x]; i < G[x].size(); i++) {
     64             Edge& e = edges[G[x][i]];
     65             if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
     66                 e.flow += f;
     67                 edges[G[x][i]^1].flow -= f;
     68                 flow += f;
     69                 a -= f;
     70                 if(a == 0) break;
     71             }
     72         }
     73         return flow;
     74     }
     75 
     76     int MaxFlow(int s, int t) {
     77         this -> s = s; this -> t = t;
     78         int flow = 0;
     79         while(BFS()) {
     80             memset(cur, 0, sizeof(cur));
     81             flow += DFS(s, INF);
     82         }
     83         return flow;
     84     }
     85 };
     86 
     87 Dinic g;
     88 
     89 map<int, int> mp;
     90 int a[maxn], b[maxn], c[maxn];
     91 int A[55][205];
     92 
     93 int n, m, num, tot;
     94 int s, t;
     95 
     96 int main() {
     97     while(EOF != scanf("%d",&n) ) {
     98         for(int i = 1; i <= n; i++) {
     99             scanf("%d %d %d",&a[i], &b[i], &c[i]);
    100             for(int j = 1; j <= a[i]; j++) {
    101                 scanf("%d",&A[i][j]);
    102             }
    103         }
    104         scanf("%d",&m);
    105         mp.clear();
    106         g.ClearAll(n * (n + 200) );
    107         s = 0; t = n + 200 + 1;
    108         int tot = n + 1;
    109         for(int i = 1; i <= n; i++) {
    110             if(i != m) {
    111                 g.AddEdge(s, i, c[i]);
    112             } else {
    113                 g.AddEdge(s, i, a[i]);
    114             }
    115             for(int j = 1; j <= a[i]; j++) {
    116                 num = A[i][j];
    117                 if(!mp[num]) mp[num] = tot++;
    118                 g.AddEdge(i, mp[num], 1);
    119             }
    120         }
    121         for(int i = n + 1; i < tot; i++) {
    122             g.AddEdge(i, t, 1);
    123         }
    124         printf("%d
    ", g.MaxFlow(s, t));
    125     }
    126     return 0;
    127 }
    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 #include <map>
     6 using namespace std;
     7 
     8 const int maxn = 205;
     9 
    10 int cap[maxn];
    11 int Link[maxn][maxn];
    12 int vLink[maxn];
    13 int mat[maxn][maxn];
    14 int vis[maxn];
    15 int n, m;
    16 
    17 bool Find(int u) {
    18     for(int i = 1; i <= m; i++) {
    19         if(!vis[i] && mat[u][i]) {
    20             int v = i;
    21             vis[v] = 1;
    22             if(vLink[v] < cap[v]) {
    23                 Link[v][vLink[v]++] = u;
    24                 return true;
    25             }
    26             for(int j = 0; j < vLink[v]; j++) {
    27                 if(Find(Link[v][j])) {
    28                     Link[v][j] = u;
    29                     return true;
    30                 }
    31             }
    32         }
    33     }
    34     return false;
    35 }
    36 
    37 int solve() {
    38     int cnt = 0;
    39     memset(Link, 0, sizeof(Link));
    40     memset(vLink, 0, sizeof(vLink));
    41     for(int i = 1; i <= n; i++) {
    42         memset(vis, 0, sizeof(vis));
    43         if(Find(i) ) cnt ++;
    44     }
    45     return cnt;
    46 }
    47 
    48 int a[maxn], b[maxn], c[maxn];
    49 int A[maxn][maxn];
    50 map<int, int> mp;
    51 
    52 int main() {
    53     int x, y;
    54     while(EOF != scanf("%d",&x) ) {
    55         for(int i = 1; i <= x; i++) {
    56             scanf("%d %d %d", &a[i], &b[i], &c[i]);
    57             for(int j = 1; j <= a[i]; j++) {
    58                 scanf("%d",&A[i][j]);
    59             }
    60         }
    61         scanf("%d",&y);
    62         mp.clear();
    63         memset(mat, 0, sizeof(mat));
    64         int tot = 1;
    65         for(int i = 1; i <= x; i++) {
    66             cap[i] = c[i];
    67             for(int j = 1; j <= a[i]; j++) {
    68                 int num = A[i][j];
    69                 if(!mp[num]) mp[num] = tot++;
    70                 mat[mp[num]][i] = 1;
    71             }
    72         }
    73         cap[y] = a[y];
    74         n = tot - 1; m = x;
    75         printf("%d
    ", solve());
    76     }
    77     return 0;
    78 }
    多重匹配
  • 相关阅读:
    Java线程池使用说明
    Java并发编程:Thread类的使用
    深入理解Java的接口和抽象类
    编程中经常看到上下文context,这个上下文指得是什么?
    context
    setContentView和inflate区别
    Java for循环的几种用法分析
    Android学习06Android应用程序的基本组件
    learning java 重定向标准输入输出
    learning java 推回输入流
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/3965143.html
Copyright © 2011-2022 走看看