Problemsetting

Time Limit: 5000ms
Memory Limit: 131072KB

64-bit integer IO format: %lld      Java class name: Main

Type:

None

 

None
 
Graph Theory
 
    2-SAT
 
    Articulation/Bridge/Biconnected Component
 
    Cycles/Topological Sorting/Strongly Connected Component
 
    Shortest Path
 
        Bellman Ford
 
        Dijkstra/Floyd Warshall
 
    Euler Trail/Circuit
 
    Heavy-Light Decomposition
 
    Minimum Spanning Tree
 
    Stable Marriage Problem
 
    Trees
 
    Directed Minimum Spanning Tree
 
    Flow/Matching
 
        Graph Matching
 
            Bipartite Matching
 
            Hopcroft–Karp Bipartite Matching
 
            Weighted Bipartite Matching/Hungarian Algorithm
 
        Flow
 
            Max Flow/Min Cut
 
            Min Cost Max Flow
 
DFS-like
 
    Backtracking with Pruning/Branch and Bound
 
    Basic Recursion
 
    IDA* Search
 
    Parsing/Grammar
 
    Breadth First Search/Depth First Search
 
    Advanced Search Techniques
 
        Binary Search/Bisection
 
        Ternary Search
 
Geometry
 
    Basic Geometry
 
    Computational Geometry
 
    Convex Hull
 
    Pick's Theorem
 
Game Theory
 
    Green Hackenbush/Colon Principle/Fusion Principle
 
    Nim
 
    Sprague-Grundy Number
 
Matrix
 
    Gaussian Elimination
 
    Matrix Exponentiation
 
Data Structures
 
    Basic Data Structures
 
    Binary Indexed Tree
 
    Binary Search Tree
 
    Hashing
 
    Orthogonal Range Search
 
    Range Minimum Query/Lowest Common Ancestor
 
    Segment Tree/Interval Tree
 
    Trie Tree
 
    Sorting
 
    Disjoint Set
 
String
 
    Aho Corasick
 
    Knuth-Morris-Pratt
 
    Suffix Array/Suffix Tree
 
Math
 
    Basic Math
 
    Big Integer Arithmetic
 
    Number Theory
 
        Chinese Remainder Theorem
 
        Extended Euclid
 
        Inclusion/Exclusion
 
        Modular Arithmetic
 
    Combinatorics
 
        Group Theory/Burnside's lemma
 
        Counting
 
    Probability/Expected Value
 
Others
 
    Tricky
 
    Hardest
 
    Unusual
 
    Brute Force
 
    Implementation
 
    Constructive Algorithms
 
    Two Pointer
 
    Bitmask
 
    Beginner
 
    Discrete Logarithm/Shank's Baby-step Giant-step Algorithm
 
    Greedy
 
    Divide and Conquer
 
Dynamic Programming
                  Tag it!

[PDF Link]

It's well-known that different programming contests require different kind of problems. For example, maximal array size for TopCoder problem is only 50, and you definitely can not give a Suffix Tree problem to IOI because children will not have a chance to solve it (except of some touristic-inclined ones). Thus not every problem is acceptable for every contest.

You are preparing problemsets for N different contests. These contests require different number of problems, depending of type. For example, ACM ICPC style problemset usually has 10 problems, TopCoder SRM - 5 and so on.

Luckily you have already prepared M different problems. For each problem you have determined a set of contests you can give that problem to. Also you know the required number of problems for each contest.

Find out the maximal number of different contests for which you can simultaneously compose complete problemsets from the given set of problems. All problems in the problemsets must be unique, i.e. no problem can be used twice in different problemsets.

 

Input

The input file contains several test cases.

The first line of each test case contains 2 integers N and M (1 < N < 15, 0 < M < 50) - the number of different contests and the number of prepared problems. Each of the followingN lines contains the name of contest, followed by the required number of problems for that contest. The name of a contest consists of lower - and uppercase Latin letters and/or digits, is not empty and does not exceed 100 characters. Contest names are case-sensitive. It's guaranteed that all contest names will be pairwise different. The required number of problems does not exceed 100.

Each of the following M lines contains a (possibly empty) list of acceptable contest names for each problem, separated by a single space. It's guaranteed that all contest names will be correct (i.e., noted in the previous section of the current test case) and unique.

The line containing two zeroes indicates the end of the input file.

For each test case print an answer for that case on a new line, as shown in the sample output.

 

Sample Input

4 5
IOI 3
IPSC 2
TopCoder 2
SEERC 10
IOI
IPSC TopCoder
IOI IPSC
IOI IPSC
TopCoder SEERC
1 1
SampleContest 1
SampleContest
0 0

Sample Output

Case #1: 2
Case #2: 1

Source

 
 
题目大意:给你n个比赛,m个题目。每个题目可以给某几个比赛用,但是只能用一次。问你在满足每个比赛需要的题目数量的条件下,最多可以办多少场比赛。
 
解题思路:用网络流可以做。我们枚举可以举办的比赛,然后从源点向所枚举的比赛加边,容量为该比赛可以选多少个题目。如果最后的最大流大于等于所枚举比赛所需题目总数,说明所枚举的比赛可以举办。更新出来最大的比赛数目即可。 构图:除了从源点向比赛加边,还需从比赛向所能使用的题目加边,容量为1,还要从题目向汇点加边,容量为1.
 
吐槽一下,这个题目的输入好像空格不均匀。
 
 
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<string>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
const int mod = 1e9+7;
const int maxn = 100;
const int INF = 0x3f3f3f3f; int Map[55][55];
int need[55];
struct Edge{
int from, to, next, cap, flow;
Edge(){}
Edge(int _from, int _to, int _cap, int _flow):from(_from), to(_to), cap(_cap),flow(_flow){}
};
int contest_table[20];
vector<Edge>edges;
vector<int>G[maxn];
void AddEdge(int from, int to, int cap){
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, 0, 0));
int m = edges.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
}
int capacity[maxn];
struct Dinic{
int s, t; // bool vis[maxn];
int d[maxn];
int cur[maxn];
bool BFS(){
memset(vis,0,sizeof(vis));
queue<int>Q;
Q.push(s);
d[s] = 0;
vis[s] = 1;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int i = 0; i < G[x].size(); ++i){
Edge &e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow){
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if(x == t || a == 0) return a;
int flow = 0, f;
for(int &i = cur[x]; i < G[x].size(); i++){
Edge &e = edges[G[x][i]];
if(d[x] + 1 == d[e.to]&&(f = DFS(e.to, min(a,e.cap - e.flow))) > 0){
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int Maxflow(int s,int t){
this->s = s; this->t = t;
int flow = 0;
while(BFS()){
memset(cur,0,sizeof(cur));
flow += DFS(s, INF);
}
return flow;
}
}; int n, m;
int constructG(int enumc){
for(int i = 0; i <= n+m+10; i++){
G[i].clear();
}
edges.clear();
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(Map[i][j]){
AddEdge(i, n+j, 1);
}
}
}
for(int i = 1; i <= m; i++){
AddEdge(n+i,n+m+1,1);
}
int ret = 0;
for(int i = 1; i <= n; i++){
if(enumc&1){
AddEdge(0, i, capacity[i]);
ret += need[i];
}
enumc /= 2;
}
return ret;
}
int main(){
string str;
int cas = 0;
char s[100000];
while(scanf("%d%d",&n,&m)!=EOF&&(n+m) != 0){
map<string,int>mp;
int c;
for(int i = 1; i <= n; i++){
scanf("%s",s);
str = s;
mp[str] = i;
scanf("%d",&need[i]);
}
memset(Map,0,sizeof(Map));
memset(capacity,0,sizeof(capacity));
getchar(); getchar();
for(int i = 1; i <= m; i++){
str = "";
gets(s);
int len = strlen(s);
for(int j = 0; j < len-1; j++) {
if(s[j]==' '&&j!=0){
if(s[j-1]!=' '){
Map[mp[str]][i]=1;
capacity[mp[str]]++;
}
str="";
}else if(s[j]!=' ') str+=s[j];
}
if(str!="") {
Map[mp[str]][i]=1;
capacity[mp[str]]++;
}
}
int enumc = (int)pow((double)2,(double)n);
int ans = 0;
Dinic ansf;
for(int i = 0; i < enumc; i++){
int j = i, cnum = 0, c = 0;
while(j){
if(j&1)
cnum++;
j = j >> 1;
}
if(ans >= cnum) continue;
int needMaxf = constructG(i);
int Maxf = ansf.Maxflow(0,n+m+1);
if(Maxf >= needMaxf){
ans = cnum;
}
}
printf("Case #%d: ",++cas);
printf("%d\n",ans);
}
return 0;
}

  

BNU 33693——Problemsetting——————【枚举+最大流】的更多相关文章

  1. hust-1024-dance party(最大流--枚举,可行流判断)

    题意: 舞会上,男孩和女孩配对,求最大完全匹配个数,要求每个人最多与k个不喜欢的人配对,且每次都和不同的人配对. 分析: 将一个点拆成3个点. b,  b1, b2.   从1到n枚举ans,  判可 ...

  2. poj 2699 The Maximum Number of Strong Kings 枚举 最大流

    题目链接 题意 对于一个竞赛图(有向完全图),其顶点是选手,边是比赛,边\(e=(u,v)\)代表该场比赛中\(u\)战胜\(v\). 现定义选手的分数为其战胜的人的个数(即竞赛图中点的出度).并且定 ...

  3. hdu4807枚举费用流

    题意:      给你一个有向图,每条边上都有每一时刻的最大流量,有k个人在点0,他们要去点n-1,问你最晚到达的那个人最快要多久. 思路:      这个题目做了很多次,用过费用流,也用过最大流,结 ...

  4. poj2699 转化为可行性判定问题+二分枚举+最大流

    The Maximum Number of Strong Kings Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2302 ...

  5. USACO 5.4 Telecowmunication(最大流+枚举)

    面对最小割之类的题目,完全木想法... 枚举+最大流..复杂度很大了...居然很快的就过了.. /* ID: cuizhe LANG: C++ TASK: telecow */ #include &l ...

  6. POJ3228 并查集或二分最大流枚举答案

    忘记写题意了.这题题意:给出每个地点的金矿与金库的数量,再给出边的长度.求取最大可通过边长的最小权值使每个金矿都能运输到金库里. 这题和之前做的两道二分枚举最大流答案的问法很相识,但是这里用最大流速度 ...

  7. Intel RealSense SDK 简翻

    :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1);border-radius:3px ...

  8. ZOJ 2676 Network Wars ★(最小割算法介绍 && 01分数规划)

    [题意]给出一个带权无向图,求割集,且割集的平均边权最小. [分析] 先尝试着用更一般的形式重新叙述本问题.设向量w表示边的权值,令向量c=(1, 1, 1, --, 1)表示选边的代价,于是原问题等 ...

  9. 最小截断[AHOI2009]

    [题目描述] 宇宙旅行总是出现一些意想不到的问题,这次小可可所驾驶的宇宙飞船所停的空间站发生了故障,这个宇宙空间站非常大,它由N个子站组成,子站之间有M条单向通道,假设其中第i(1<=i< ...

随机推荐

  1. c#用表达式树实现深拷贝功能

    因为对表达式树有点兴趣,出于练手的目的,试着写了一个深拷贝的工具库.支持.net standard2.0或.net framework4.5及以上. GitHub地址https://github.co ...

  2. C#多线程学习(二) 如何操纵一个线程

    在C#中,线程入口是通过ThreadStart代理(delegate)来提供的,你可以把ThreadStart理解为一个函数指针,指向线程要执行的函数,当调用Thread.Start()方法后,线程就 ...

  3. Major Performance Impacts

    - Default opaque flags (3s) - Filter size (3s) - ??? (4s) - Image refresh performance (1s)

  4. MVC ASP.NET MVC5使用Area区域

    MVC  ASP.NET MVC5使用Area区域 一.为什么要使用area? 在大型的ASP.NET mvc5项目中一般都有许多个功能模块,这些功能模块可以用Area(中文翻译为区域)把它们分离开来 ...

  5. webstorm中新建vue工程

    1.在https://nodejs.org/en/下载安装nodejs 2.vue-cli 搭建框架 首先从官方网站安装 node.js,会一并安装 npm工具.注意 npm一定要3.10以上,以免很 ...

  6. Ubuntu16.04实用python脚本 - JDK的配置!

    前提已经把Oracle JDK解压缩到指定目录了,我的JDK目录是:“/usr/jdk1.8.0_121” 全部脚本: # coding=utf-8 ,中文注释需要加入编码格式 #这是我的测试文件,在 ...

  7. 洛谷P3706 [SDOI2017]硬币游戏(概率生成函数+高斯消元)

    题面 传送门 题解 不知道概率生成函数是什么的可以看看这篇文章,题解也在里面了 //minamoto #include<bits/stdc++.h> #define R register ...

  8. [Objective-C语言教程]循环语句(9)

    当需要多次执行同一代码块时,可以使用循环来解决. 通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推. 编程语言提供各种控制结构,允许更复杂的执行路径.循环语句可用于多次执 ...

  9. exec和xargs

    参考:http://www.cnblogs.com/itxdm/p/5936907.html 一. 先复习下find命令 1. name参数 find -name tom 或 find -iname ...

  10. javascript 动态脚本添加

    异步加载js文件或者异步加载js模块,支持所有浏览器,包括IE,参考至javascript高级编程 1.createScript方法用于创建一个script标签并添加到body标签中 2.create ...