UOJ 79 带花树入门
来源:互联网 发布:苹果mac怎么关闭程序 编辑:程序博客网 时间:2024/06/06 12:45
从前一个和谐的班级,所有人都是搞OI的。有 nn 个是男生,有 00 个是女生。男生编号分别为 1,…,n1,…,n。
现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人负责吐槽。每个人至多属于一个小组。
有若干个这样的条件:第 vv 个男生和第 uu 个男生愿意组成小组。
请问这个班级里最多产生多少个小组?
输入格式
第一行两个正整数,n,mn,m。保证 n≥2n≥2。
接下来 mm 行,每行两个整数 v,uv,u 表示第 vv 个男生和第 uu 个男生愿意组成小组。保证 1≤v,u≤n1≤v,u≤n,保证 v≠uv≠u,保证同一个条件不会出现两次。
输出格式
第一行一个整数,表示最多产生多少个小组。
接下来一行 nn 个整数,描述一组最优方案。第 vv 个整数表示 vv 号男生所在小组的另一个男生的编号。如果 vv 号男生没有小组请输出 00。
样例一
input
10 20
9 2
7 6
10 8
3 9
1 10
7 1
10 9
8 6
8 2
8 1
3 1
7 5
4 7
5 9
7 8
10 4
9 1
4 8
6 3
2 5
output
5
9 5 6 10 2 3 8 7 1 4
样例二
input
5 4
1 5
4 2
2 1
4 3
output
2
2 1 4 3 0
限制与约定
1≤n≤5001≤n≤500,1≤m≤1247501≤m≤124750。
时间限制:1s1s
空间限制:256MB256MB
#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<vector>#include<queue>using namespace std;#define LL long long#define pb push_back#define Set(a, v) memset(a, v, sizeof(a))#define For(i, a, b) for(int i = (a); i <= (int)(b); i++)#define Forr(i, a, b) for(int i = (a); i >= (int)(b); i--)#define MAXN (500+5)struct BlossomTree{ vector<int> G[MAXN]; queue<int> q; int n; int pre[MAXN], link[MAXN], col[MAXN], fa[MAXN]; bool vis[MAXN]; void init(int rn){ n = rn; Set(link, 0); For(i, 0, n) G[i].clear(); } void Addedges(int u, int v){ G[u].pb(v); G[v].pb(u); } int find(int x){ return x == fa[x]? x: (fa[x] = find(fa[x])); } void Combine(int u, int lca){ while(u != lca){ int f = link[u], g = pre[f]; if(find(g) != lca) pre[g] = f; //put the rever edge if(col[f] == 1) col[f] = 2, q.push(f); fa[find(u)] = find(f); fa[find(f)] = find(g); u = pre[link[u]]; } } void Contract(int u, int v){ Set(vis, 0); int lca = 0; for(int i = u; i; i = pre[link[i]]) i = find(i), vis[i] = true; for(int i = v; i; i = pre[link[i]]){ i = find(i); if(vis[i]){lca = i; break;} } if(find(u) != lca) pre[u] = v; if(find(v) != lca) pre[v] = u; Combine(u, lca); Combine(v, lca); } void Bfs(int s){ while(!q.empty()) q.pop(); Set(col, 0); Set(pre, 0); For(i, 1, n) fa[i] = i; q.push(s); while(!q.empty()){ int now = q.front(); q.pop(); For(i, 0, G[now].size()-1){ int v = G[now][i]; if(find(now)==find(v) || link[now]==v || col[v]==1) continue; if(col[v] == 2) Contract(now, v); else if(link[v]){ pre[v] = now; col[v] = 1; col[link[v]] = 2; q.push(link[v]); }else{ pre[v] = now; int g = link[now], f = now, o = v; while(o){ link[f] = o; link[o] = f; o = g; f = pre[o]; g = link[f]; } return; } } } } int MaxMatch(){ For(i, 1, n) if(!link[i]) Bfs(i); int ret = 0; For(i, 1, n) if(link[i]) ret++; return ret/2; } void print(){ printf("%d", link[1]); For(i, 2, n) printf(" %d", link[i]); printf("\n"); }}BT;int main(){ int n, m; scanf("%d%d", &n, &m); BT.init(n); For(i, 1, m){ int u, v; scanf("%d%d", &u, &v); BT.Addedges(u, v); } printf("%d\n", BT.MaxMatch()); BT.print(); return 0;}
1 0
- UOJ 79 带花树入门
- UOJ-79 一般图的最大匹配(带花树模板求解)
- uoj 34 多项式乘法(fft入门)
- 【UOJ#97】一般图最大匹配【带花树】
- 【UOJ#171】【WC2016】挑战NPC【带花树】
- uoj 79 一般图最大匹配
- UOJ 一般图的最大匹配(带花树算法模板)
- 带花树算法 UOJ#79. 一般图最大匹配
- 带花树算法 UOJ#79. 一般图最大匹配
- [UOJ 118][UOJ Round #8]赴京赶考
- UOJ Round5总结
- 【UOJ Goodbye Jiawu】
- 【UOJ #6】AB题解
- uoj 104 [apio2014 T2]
- Uoj#9感想
- uoj#35: 后缀排序
- Uoj#35. 后缀排序
- 【uoj #35】后缀排序
- HDU4576 Robot 概率DP
- mysql学习历程
- Sort the Array (CF)
- SPOJ - Linearian Colony【分解为子问题】
- 【NOIP2014八校联考第2场第2试9.28】分组(group)
- UOJ 79 带花树入门
- 使用策略模式进行简单的form验证
- uoj 279: [UTR #2]题目交流通道 动态规划
- nginx过滤器模块
- LCD12864 为什么就是显示不了内容!
- 步步扎进Java-面向对象
- bzoj 2820: YY的GCD 莫比乌斯反演
- 图解Linux命令之--comm命令
- liferay ga6获取当前语言环境