首页 > 代码库 > zoj 3642 Just Another Information Sharing Problem【最大流||多重匹配】

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\n", 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\n", solve());76     }77     return 0;78 }
多重匹配

 

zoj 3642 Just Another Information Sharing Problem【最大流||多重匹配】