URAL 1099 Work Scheduling(一般图匹配模板)
2015-07-16 13:59
357 查看
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <algorithm> #include <cmath> #include <cstdlib> #include <stack> #include <queue> #include <map> #include <vector> #include <cstdlib> #include <set> using namespace std; #define LL long long #define N 520 #define M 400020 #define eps 1e-8 #define MP make_pair #define Pi acos(-1.0) #pragma comment(linker, "/STACK:1024000000,1024000000") #define inf 0x3f3f3f3f #define ls (i << 1) #define rs (ls | 1) #define md ((ll + rr) >> 1) #define lson ll, md, ls #define rson md + 1, rr, rs #define mod 1000000007 struct graph { int n, match ; bool adj ; void clear(int nn = 0) { n = nn; memset(adj, 0, sizeof adj); } void add(int u, int v) { adj[u][v] = adj[v][u] = 1; } int gao() { memset(match, -1, sizeof match); int ans = 0; for(int i = 1; i <= n; ++i) { if(match[i] == -1) ans += bfs(i); } return ans; } int q , pre , base ; bool inq , inblossom ; int bfs(int p) { memset(pre, -1, sizeof pre); memset(inq, 0, sizeof inq); for(int i = 1; i <= n; ++i) base[i] = i; q[0] = p; inq[p] = 1; for(int s = 0, t = 1; s < t; ++s) { int u = q[s]; for(int v = 1; v <= n; ++v) { if(adj[u][v] && base[u] != base[v] && v != match[u]) { if(v == p || (match[v] != -1 && pre[match[v]] != -1)) { int b = contract(u, v); for(int i = 1; i <= n; ++i) { if(inblossom[base[i]]) { base[i] = b; if(inq[i] == 0) { inq[i] = 1; q[t++] = i; } } } } else if(pre[v] == -1) { pre[v] = u; if(match[v] == -1) { aug(v); return 1; } else { q[t++] = match[v]; inq[match[v]] = 1; } } } } } return 0; } void aug(int u) { while(u != -1) { int v = pre[u]; int k = match[v]; match[u] = v; match[v] = u; u = k; } } void change_blossom(int b, int u) { while(base[u] != b) { int v = match[u]; inblossom[base[v]] = inblossom[base[u]] = 1; u = pre[v]; if(base[u] != b) { pre[u] = v; } } } int contract(int u, int v) { memset(inblossom, 0, sizeof inblossom); int b = lca(base[u], base[v]); change_blossom(b, u); change_blossom(b, v); if(base[u] != b) { pre[u] = v; } if(base[v] != b) pre[v] = u; return b; } int lca(int u, int v) { bool in_path ; memset(in_path, 0, sizeof in_path); while(1) { in_path[u] = 1; if(match[u] == -1) break; u = base[pre[match[u]]]; } while(!in_path[v]) { v = base[pre[match[v]]]; } return v; } }g; int n; int main() { scanf("%d", &n); g.clear(n); int x, y; while(scanf("%d%d", &x, &y) != EOF) { g.add(x, y); } bool mark ; memset(mark, 0, sizeof mark); int ans = g.gao(); printf("%d\n", ans * 2); for(int i = 1; i <= n; ++i) { if(g.match[i] != -1 && mark[i] == 0 && mark[g.match[i]] == 0) { printf("%d %d\n", i, g.match[i]); mark[i] = mark[g.match[i]] = 1; } } return 0; }
搜索
复制
相关文章推荐
- 深入浅出SharePoint——配置List通过邮件来接收内容
- 操盘策略:股价异动未必主力所为
- css样式float造成的浮动“塌陷”问题的解决办法
- LoadManger使用详解(六)--举例
- Spring定时任务
- MFC中消息机制之实现多窗体信息的传输
- 15款创建漂亮幻灯片的 jQuery 插件
- [C#HttpHelper]类1.4正式版教程与升级报告
- C# winform 打印事例
- Android Activity 常用功能设置(全屏、横竖屏等)
- EasyUI datagird 排序 按数字类型的问题
- 使用低版本Jackson 2的类级@JsonInclude包含策略的bug
- 在Windows上使用mongodb
- List实现
- shell-自动部署war包到tomcat
- Linux LVM学习总结——扩展卷组VG
- 动态主机配置协议(DHCP)如何启动和关闭
- Linux下Web服务器环境搭建LNMP一键安装包 v2.6
- 值类型数据和引用类型数据
- CATALOG DATABASE command