二分+二分图多重匹配。

 /* 1669 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxn = ;
const int maxm = ;
bool M[maxn][maxm];
bool visit[maxm];
int can[maxm][maxm];
int sz[maxm];
int n, gn, bound; bool dfs(int u) {
rep(i, , gn) {
if (M[u][i] && !visit[i]) {
visit[i] = true;
if (sz[i] < bound) {
can[i][sz[i]++] = u;
return true;
}
rep(j, , sz[i]) {
if (dfs(can[i][j])) {
can[i][j] = u;
return true;
}
}
}
} return false;
} bool judge(int bound_) {
bound = bound_;
memset(sz, , sizeof(sz));
rep(i, , n) {
memset(visit, false, sizeof(visit));
if (!dfs(i))
return false;
} return true;
} void solve() {
int l, r, mid;
int ans; l = ;
ans = r = n;
while (l <= r) {
mid = (l + r) >> ;
if (judge(mid)) {
ans = mid;
r = mid - ;
} else {
l = mid + ;
}
} printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif char name[];
int gid;
char ch; while (scanf("%d %d", &n, &gn)!=EOF && (n||gn)) {
memset(M, false, sizeof(M));
rep(i, , n) {
scanf("%s", name);
while () {
scanf("%d%c", &gid, &ch);
M[i][gid] = true;
if (ch == '\n')
break;
}
}
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

二分+网络流Dinic也可以解。

 /* 1669 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 typedef struct {
int v, c, nxt;
} Edge_t; const int INF = 0x3f3f3f3f;
const int maxn = ;
const int maxm = ;
const int maxv = maxn + maxm;
const int maxe = maxn*maxm*+;
Edge_t E[maxe];
int F[maxe];
int head[maxv], head_[maxv];
int id[maxm];
int dis[maxv], Q[maxv];
int m;
int n, gn;
int s, t; void init() {
memset(head, -, sizeof(head));
m = ;
s = ;
t = n + gn + ;
} void addEdge(int u, int v, int c) {
E[m].v = v;
E[m].c = c;
E[m].nxt = head[u];
head[u] = m++; E[m].v = u;
E[m].c = ;
E[m].nxt = head[v];
head[v] = m++;
} bool bfs() {
int l = , r = ;
int u, v, k; Q[r++] = s;
memset(dis, , sizeof(dis));
dis[s] = ; while (l < r) {
u = Q[l++];
for (k=head[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (!dis[v] && E[k].c>F[k]) {
dis[v] = dis[u] + ;
if (v == t)
return false;
Q[r++] = v;
}
}
} return true;
} int dfs(int u, int val) {
if (u==t || val==)
return val; int ret = ;
int tmp, v; for (int& k=head_[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (dis[v]==dis[u]+ && E[k].c>F[k] && (tmp=dfs(v, min(val, E[k].c-F[k])))>) {
F[k] += tmp;
F[k^] -= tmp;
ret += tmp;
val -= tmp;
if (val == )
break;
}
} return ret;
} int Dinic() {
int ret = , tmp; while () {
if (bfs())
break; memcpy(head_, head, sizeof(head));
while () {
tmp = dfs(s, INF);
if (tmp == )
break;
ret += tmp;
}
}
#ifndef ONLINE_JUDGE
printf("Dinic = %d\n", ret);
#endif
return ret;
} bool judge(int bound) {
rep(i, , gn+)
E[id[i]].c = bound;
memset(F, , sizeof(F)); return Dinic()>=n;
} void solve() {
int l = , r = n, mid;
int ans = -; while (r >= l) {
mid = (l + r) >> ;
if (judge(mid)) {
ans = mid;
r = mid - ;
} else {
l = mid + ;
}
} printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif char name[];
char ch;
int gid; while (scanf("%d %d", &n, &gn)!=EOF && (n||gn)) {
init();
rep(i, , n+) {
scanf("%s", name);
while () {
scanf("%d%c", &gid, &ch);
addEdge(i, gid+n+, );
if (ch == '\n')
break;
}
}
rep(i, , n+)
addEdge(s, i, );
rep(i, , gn+) {
id[i] = m;
addEdge(n+i, t, );
}
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

【HDOJ】1669 Jamie's Contact Groups的更多相关文章

  1. HDU 1669 Jamie's Contact Groups(多重匹配+二分枚举)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1669 题目大意: 给你各个人可以属于的组,把这些人分组,使这些组中人数最多的组人数最少,并输出这个人数 ...

  2. poj 2289 Jamie's Contact Groups【二分+最大流】【二分图多重匹配问题】

    题目链接:http://poj.org/problem?id=2289 Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K ...

  3. POJ 2289——Jamie's Contact Groups——————【多重匹配、二分枚举匹配次数】

    Jamie's Contact Groups Time Limit:7000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I ...

  4. POJ 2289 Jamie's Contact Groups / UVA 1345 Jamie's Contact Groups / ZOJ 2399 Jamie's Contact Groups / HDU 1699 Jamie's Contact Groups / SCU 1996 Jamie's Contact Groups (二分,二分图匹配)

    POJ 2289 Jamie's Contact Groups / UVA 1345 Jamie's Contact Groups / ZOJ 2399 Jamie's Contact Groups ...

  5. POJ2289 Jamie's Contact Groups(二分图多重匹配)

    Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 7721   Accepted: ...

  6. Jamie's Contact Groups POJ - 2289(多重匹配 最大值最小化 最大流)

    Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 8567   Accepted: ...

  7. POJ 2289 Jamie's Contact Groups 二分图多重匹配 难度:1

    Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 6511   Accepted: ...

  8. POJ2289:Jamie's Contact Groups(二分+二分图多重匹配)

    Jamie's Contact Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/ ...

  9. POJ2289 Jamie's Contact Groups —— 二分图多重匹配/最大流 + 二分

    题目链接:https://vjudge.net/problem/POJ-2289 Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 6 ...

随机推荐

  1. ###《Effective STL》--Chapter3

    点击查看Evernote原文. #@author: gr #@date: 2014-09-13 #@email: forgerui@gmail.com Chapter3 关联容器 Topic 22: ...

  2. StrHelper

    public class StrHelper { private static string passWord; //加密字符串 /// <summary> /// 判断输入是否数字 // ...

  3. ZOJ 2624 Popo's Lamps(DP 记忆化搜索)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2624 题目大意:popo要将给定数量的灯变成自己想要的颜色,有一 ...

  4. (int)、(int&)和(int*)的区别(转)

    (1).首先通过一个例子看(int)和(int&)的区别: float a = 1.0f;cout << (int)a << endl;cout << (i ...

  5. 程序员面试题精选100题(33)-在O(1)时间删除链表结点[数据结构]

    作者:何海涛 出处:http://zhedahht.blog.163.com/ 题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode { ...

  6. Headfirst设计模式的C++实现——状态模式(State)

    state.h #ifndef _STATE_H_ #define _STATE_H_ class GumballMachine; class State { public: ; ; ; ; Stat ...

  7. Class类文件的结构

    Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,中间没有任何分隔符.Class文件的结构只有两种数据类型:无符号数和表.无符号数以u1.u2. ...

  8. 【转】Ubuntu编译安装mysql源码

    主要参考了下面两篇文章 http://forum.ubuntu.org.cn/viewtopic.php?t=330121 http://www.linuxidc.com/Linux/2011-09/ ...

  9. mysql基本知识

    最大连接数show variables max_connections; select VARIABLE_VALUE from information_schema.GLOBAL_VARIABLES ...

  10. CSS display:inline和float:left两者区别探讨

     本文和大家重点讨论一下CSS display:inline和float:left两者的区别,CSS display是指显示状态,inline表示内联,特点是紧贴着前一个内联元素,通常默认的内联元素有 ...