二分+二分图多重匹配。

 /* 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. Oracle 递归函数与拼接

    ) name FROM table tb START ) CONNECT BY PRIOR ID=mt.parentid ; 在Oracle中,SYS_CONNECT_BY_PATH函数主要作用是可以 ...

  2. 学习块格式化上下文(BlockFormattingContext)

    什么是BFC BFC全称是Block Formatting Context,即块格式化上下文.它是CSS2.1规范定义的,关于CSS渲染定位的一个概念.要明白BFC到底是什么,首先来看看什么是视觉格式 ...

  3. LNK1169 和 LNK2005

    错误重现: 1> vs2010创建 C++ win32 project, Application type: DLL. 2>为了在工程中使用 CString, 在 stdafx.h 中 I ...

  4. ubuntu的syslog为空,停止写入解决方法

    修改syslog权限: chown syslog:adm syslog

  5. Linux下UDP收/发广播消息简单实现

    发送广播消息 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/typ ...

  6. Vsftpd -- 验证方式

    vsftpd程序提供的FTP服务可选认证方式,分别为匿名访问.本地用户和虚拟用户: 匿名访问:任何人无需验证口令即可登入FTP服务端. 本地用户:使用FTP服务器中的用户.密码信息. 虚拟用户:创建独 ...

  7. hdu 5055 Bob and math problem

    先把各个数字又大到小排列,如果没有前导零并且为奇数,则直接输出.如果有前导零,则输出-1.此外,如果尾数为偶数,则从后向前找到第一个奇数,并把其后面的数一次向前移动,并把该奇数放到尾部. 值得注意的是 ...

  8. CSS选择器,标签限定

    例子:ul#nav, ul li#nav和 #nav ul, #nav ul li 注意空格,没有空间隔开的就可以理解为限定 区别 1.ul#nav:表示id='nav'的ul:(ul限定#nav标签 ...

  9. c#WebBrowser进阶

    WebBrowser的基本功能就是访问网页,但是由于它本身就不在主线程上面,所以程序判断它什么时候加载完成了,比较麻烦.为此我集合从网上找到的内容,做了一个例子. 其中包括了给WebBrowser设置 ...

  10. C#动态生成图书信息XML文件

    通过C#动态生成图书信息XML文件,下面有个不错的示例,需要的朋友可以参考下 通过C#动态生成图书信息XML文件(Books.xml),文件如下: 复制代码代码如下: <?xml version ...