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 }
多重匹配

 

转载于:https://www.cnblogs.com/zhanzhao/p/3965143.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值