hdu 5352 匈牙利(多重匹配)
2015-08-05 19:53
411 查看
由于实在不想拆点,写了个这样的代码:
不过很可惜,这份代码是过不去的,具体原因我还没有找到。
只好乖乖拆点了...
#include <iostream> #include <cstring> #include <cstdio> #include <set> using namespace std; const int N = 5000; bool g ; bool g2 ; bool visit ; set<int> mark ; set<int>::iterator it; int n, m, mm, k; void dfs1( int u ) { visit[u] = 1; for ( int i = 1; i <= n; i++ ) { if ( !visit[i] && g[u][i] ) { dfs1(i); } } } int dfs2( int u ) { for ( int i = mm; i >= 1; i-- ) { if ( !visit[i] && g2[u][i] ) { visit[i] = 1; if ( mark[i].size() < k ) { mark[i].insert(u); return 1; } for ( it = mark[i].begin(); it != mark[i].end(); it++ ) { if ( dfs2((*it)) ) { mark[i].erase((*it)); mark[i].insert(u); return 1; } } } } return 0; } void hungary() { for ( int i = 1; i <= mm; i++ ) { mark[i].clear(); } int res = 0; for ( int i = 1; i <= n; i++ ) { memset( visit, 0, sizeof(visit) ); res += dfs2(i); } printf("%d\n", res); for ( int i = 1; i <= mm; i++ ) { printf("%d", mark[i].size()); if ( i != mm ) putchar(' '); else putchar('\n'); } } int main () { int t; scanf("%d", &t); while ( t-- ) { scanf("%d%d%d", &n, &m, &k); mm = 0; memset( g, 0, sizeof(g) ); memset( g2, 0, sizeof(g2) ); while ( m-- ) { int op; scanf("%d", &op); if ( op == 1 ) { mm++; int r; scanf("%d", &r); memset( visit, 0, sizeof(visit) ); dfs1(r); for ( int j = 1; j <= n; j++ ) { if ( visit[j] ) { g2[j][mm] = 1; } } } else if ( op == 2 ) { int u, v; scanf("%d%d", &u, &v); g[u][v] = g[v][u] = 1; } else if ( op == 3 ) { int q; scanf("%d", &q); while ( q-- ) { int u, v; scanf("%d%d", &u, &v); g[u][v] = g[v][u] = 0; } } } hungary(); } return 0; }
不过很可惜,这份代码是过不去的,具体原因我还没有找到。
只好乖乖拆点了...
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 501; const int M = 7000; const int K = 300000; bool g ; bool visit ; int head[M]; int mark ; int ans ; int table ; int n, m, k, p, e, ptr; struct Edge { int v, next; } edge[K]; void addEdge( int u, int v ) { edge[e].v = v; edge[e].next = head[u]; head[u] = e++; } void dfs1( int u ) { visit[u] = 1; table[ptr++] = u; for ( int i = 1; i <= n; i++ ) { if ( !visit[i] && g[u][i] ) { dfs1(i); } } } int dfs2( int u ) { for ( int i = head[u]; i != -1; i = edge[i].next ) { int v = edge[i].v; if ( !visit[v] ) { visit[v] = 1; if ( mark[v] == -1 || dfs2(mark[v]) ) { mark[v] = u; return 1; } } } return 0; } void hungary() { int res = 0; memset( mark, -1, sizeof(mark) ); memset( ans, 0, sizeof(ans) ); for ( int i = p - 1; i >= 0; i-- ) { for ( int j = i * k + 1; j <= ( i + 1 ) * k; j++ ) { memset( visit, 0, sizeof(visit) ); if ( dfs2(j) ) { res++; ans[i]++; } } } printf("%d\n", res); for ( int i = 0; i < p - 1; i++ ) { printf("%d ", ans[i]); } printf("%d\n", ans[p - 1]); } int main () { int t; scanf("%d", &t); while ( t-- ) { scanf("%d%d%d", &n, &m, &k); e = p = 0; memset( head, -1, sizeof(head) ); memset( g, 0, sizeof(g) ); while ( m-- ) { int op; scanf("%d", &op); if ( op == 1 ) { int r; scanf("%d", &r); memset( visit, 0, sizeof(visit) ); ptr = 0; dfs1(r); for ( int j = 0; j < ptr; j++ ) { for ( int y = p * k + 1; y <= ( p + 1 ) * k; y++ ) { addEdge( y, table[j] ); } } p++; } else if ( op == 2 ) { int u, v; scanf("%d%d", &u, &v); g[u][v] = g[v][u] = 1; } else if ( op == 3 ) { int q; scanf("%d", &q); while ( q-- ) { int u, v; scanf("%d%d", &u, &v); g[u][v] = g[v][u] = 0; } } } hungary(); } return 0; }
相关文章推荐
- WPF_图片黑白处理
- h264码流分析及其工具
- hdoj 5008 后缀数组+RMQ+二分
- Eclipse下使用maven创建多模块项目
- 创客 机械臂坦克电机不转问题
- SVM 多分类 -SVM分类opencv3.0源代码
- Android ListView中点击单行实现RadioButton的单选功能,自定义Item布局文件
- 深入分析android5.1 healthd
- 关于Orcale中not in与空值在查询上的问题
- linux下安装mongodb
- 网络应用发布到linux上的web服务器上页面上显示麻将牌式字符的问题
- ANDROID中去掉ACTIONBAR或TABWIDGET的分隔线
- JDK安装
- 08-05 Server、Client可连续发送 生产者、消费者 死锁解决 Server、Client窗口实现
- 如何用create table ... as select ...建与另一个实例中的用户下表结构相同的表
- POJ 2242 The Circumference of the Circle 简单数学
- android timessquare日期控件
- *(volatile unsigned long *) 语法
- C#高级编程小结
- 《集体失忆的黑暗时代》:已故加拿大公共知识分子关于城市规划与人类文明的随笔,三星推荐