The UN finals are here!, the coaches/ex-coaches team is creating a new exciting contest to select which teams will compete in the Colombian finals. Ivan said: the rules are clear, the only limitation to enroll teams in the Colombian finals is to pick a maximum of k teams per career. A team can be labeled with career X if there is no career Y such that more team members are enrolled in career Y than in career X. Finally, each team consists of three students (as usual).

Someone in the UN campus (UN finals are pretty popular) said, hey you guys should pick the teams careers in such a way that it maximizes the number of enrolled teams. Diego said: ah that is too easy. You will prove Diego right (or wrong). Given the description of the teams, output the maximum number of teams that can be enrolled in the Colombian finals.

Input

The first line is n (1 ≤ n ≤ 100) - the number of teams that registered to participate in the UN finals.

Next n lines contains each the
information from each team, that is, there will be three strings per
team (one per team member) separated by a single space. Each string
consists of distinct upper case letters which represent the careers that
a team member is studying (UN students love to study multiple careers).

The last line contains an integer k (1 ≤ k ≤ n) - the maximum allowed number of teams per career.

Output

Print a single integer - the maximum number of teams that can be enrolled.

Example

Input
5
A ABC B
C C C
B B B
A A A
C AC CB
2
Output
5

Note

In the first example first and fourth team can represent career A, second and fifth team can represent career C and third can represent team B.

吐槽一点:数据真水,我模拟都过了。。

应该是网络流的裸题;

至于匹配问题的话,匈牙利也可以;

不过网络流建边也比较容易;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 200005
#define inf 0x7fffffff
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-4
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
ll x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
} ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
int sqr(int x) { return x * x; } /*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1; y = 0; return a;
}
ans = exgcd(b, a%b, x, y);
ll t = x; x = y; y = t - a / b * y;
return ans;
}
*/ int n;
int k; string s[104][3];
map<char, int>mp;
int fg[103][30];
int vis[2000];
int str[1003];
int car[103];
int st, ed;
struct node {
int u, v, nxt, w;
}edge[maxn << 1]; int head[maxn], cnt; void addedge(int u, int v, int w) {
edge[cnt].u = u; edge[cnt].v = v; edge[cnt].nxt = head[u];
edge[cnt].w = w; head[u] = cnt++;
} int rk[maxn]; int bfs() {
queue<int>q;
ms(rk);
rk[st] = 1;
q.push(st);
while (!q.empty()) {
int tmp = q.front(); q.pop();
for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
int to = edge[i].v;
if (rk[to] || edge[i].w <= 0)continue;
rk[to] = rk[tmp] + 1; q.push(to);
}
}
return rk[ed];
} int dfs(int u, int flow) {
if (u == ed)return flow;
int add = 0;
for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
int v = edge[i].v;
if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
int tmpadd = dfs(v, min(edge[i].w, flow - add));
if (!tmpadd) { rk[v] = -1; continue; }
edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd;
add += tmpadd;
}
return add;
} int ans;
void dinic() {
while (bfs())ans += dfs(st, inf);
} int main() {
// ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> n; memset(head, -1, sizeof(head));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 3; j++)cin >> s[i][j];
}
cin >> k;
for (int i = 1; i <= n; i++) {
mp.clear();
for (int j = 1; j <= 3; j++) {
for (int y = 0; y < s[i][j].length(); y++) {
mp[s[i][j][y]]++;
}
}
int maxx = -1;
for (char ch = 'A'; ch <= 'Z'; ch++) {
maxx = max(maxx, mp[ch]);
}
for (char ch = 'A'; ch <= 'Z'; ch++) {
if (mp[ch] == maxx) {
fg[i][ch - 'A' + 1] = 1;
}
}
}
st = 0; ed = 1000;
for (int i = 1; i <= n; i++)addedge(st, i, 1), addedge(i, st, 0);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 26; j++) {
if (fg[i][j]) {
addedge(i, j + n + 1, 1); addedge(j + 1 + n, i, 0);
}
}
}
for (int i = 1; i <= 26; i++)addedge(i + n + 1, ed, k), addedge(ed, i + 1 + n, 0);
dinic();
cout << ans << endl;
return 0;
}

Gym - 101845F 最大流的更多相关文章

  1. Codeforces Gym 100002 E "Evacuation Plan" 费用流

    "Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...

  2. 【最大流】ECNA 2015 F Transportation Delegation (Codeforces GYM 100825)

    题目链接: http://codeforces.com/gym/100825 题目大意: N(N<=600)个点,每个点有个名字Si,R(R<=200)个生产商在R个点上,F(F<= ...

  3. 【最大流】BAPC2014 A Avoiding the Apocalypse (Codeforces GYM 100526)

    题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...

  4. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  5. Gym 101981I - Magic Potion - [最大流][2018-2019 ACM-ICPC Asia Nanjing Regional Contest Problem I]

    题目链接:http://codeforces.com/gym/101981/attachments There are n heroes and m monsters living in an isl ...

  6. Gym - 101908G Gasoline 二分+最大流

    G - Gasoline Gym - 101908G 题意:给出R个提供点,P个接收点,每个接收点都要接收满,还有一个运输的时间,问最小时间能够完成所有的运输 题解:首先每次都必须要满流,所以我们只要 ...

  7. Codeforces Gym 100733I The Cool Monkeys 拆点+最大流

    原题链接:http://codeforces.com/gym/100733/problem/I 题意 有两颗树(只是树,不是数据结构),每棵树上有不同高度的树枝,然后有m只猴子在某棵树的前m高的树枝上 ...

  8. Codeforces Gym 100203I I WIN 最大流

    原题链接:http://codeforces.com/gym/100203/attachments/download/1702/statements.pdf 题解 首先寻找每个I,然后枚举形状,如果匹 ...

  9. Gym - 102346G Getting Confidence 最小费用最大流

    Gym - 102346GGetting Confidence 题意:n*n的格子,每个格子上有一个数,要求每行每列都只能拿一个数,使得乘积最大,然后输出每列选择的是第几行的数. 如果是加法的话,那么 ...

随机推荐

  1. [转]浅谈javascript函数劫持

    转自:Ph4nt0m Security Team 这么多年了,现在学习依然还是有很多收货,向前辈致敬.转载一方面是自己存档一份,另一方面是让更多喜欢安全的人一同学习. ================ ...

  2. vuex的实用知识点

    本文系统介绍vuex的全部内容 为什么用vuex 组件通信知道吧,相信很多同学,刚学的时候很难懂,实时上在实际应用中,大型项目如果使用最原始的组件通信会非常的麻烦,主要体现在多层嵌套的组件之间的通信, ...

  3. Camera.Parameters 参数 <转>

    http://blog.csdn.net/aiqing0119/article/details/27680137 ------------------------------------------- ...

  4. linux中安装sqlmap

    wget https://codeload.github.com/sqlmapproject/sqlmap/legacy.tar.gz/master //下载sqlmap tar zxvf maste ...

  5. CentOS6.5 增加交换空间

    在CentOS 6.5安装Oracle 11g的时候,提示交换空间不足,百度来下,找到来增加交换空间的方法,特此记录一下 增加交换空间有两种方法: 严格的说,在系统安装完后只有一种方法可以增加swap ...

  6. re.spilt

  7. Android中pull解析XML文件的简单使用

    首先,android中解析XML文件有三种方式,dom,sax,pull 这里先讲pull,稍候会说SAX和DOM pull是一种事件驱动的xml解析方式,不需要解析整个文档,返回的值是数值型,是推荐 ...

  8. php学习笔记-return语句

    一个函数中可以有return语句,也可以没有.什么时候需要呢?就是当你想接收函数的执行结果的时候,你需要一个return 语句. 函数执行完return语句之后,return语句后面的代码是永远不会得 ...

  9. php学习笔记-for循环

    for(init;condition;statement) { func(); } for循环的执行逻辑是先执行一次init语句,然后判断condition是否为true,是则执行func(),再执行 ...

  10. 612D The Union of k-Segments

    传送门 题目大意 给定n个区间,问你被覆盖至少k次的区间(两端连续区间可以合并)最少有多少个,并输出. 分析 大水题呀QwQ,只需要将每个点的位置及它是左端点还是右端点这两个信息存起来然后进行一些简单 ...