Ural 1099 Work Scheduling
2016-07-18 20:33
225 查看
http://acm.timus.ru/problem.aspx?space=1&num=1099
题意:有n个人,很多对合作关系,每个人只能和一个人合作,求最多能选出多少人。
一般图匹配
题意:有n个人,很多对合作关系,每个人只能和一个人合作,求最多能选出多少人。
一般图匹配
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> int head,tail; bool G[300][300],inpath[300],inqueue[300],inblossom[300]; int start,finish,father[300],base[300]; int q[300],n,match[300],newbase; int read(){ int t=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f; } void init(){ int x,y; memset(G,0,sizeof G); n=read(); while (scanf("%d%d",&x,&y)!=EOF){ G[x][y]=G[y][x]=1; } } int lca(int u,int v){ memset(inpath,0,sizeof (inpath)); while (true){ u=base[u]; inpath[u]=1; if (u==start) break; u=father[match[u]]; } while (true){ v=base[v]; if (inpath[v]) break; v=father[match[v]]; } return v; } void resettrace(int u){ int v; while (base[u]!=newbase){ v=match[u]; inblossom[base[u]]=inblossom[base[v]]=1; u=father[v]; if (base[u]!=newbase) father[u]=v; } } void blossomcontract(int u,int v){ newbase=lca(u,v); memset(inblossom,0,sizeof (inblossom)); resettrace(u); resettrace(v); if (base[u]!=newbase) father[u]=v; if (base[v]!=newbase) father[v]=u; for (int tu=1;tu<=n;tu++) if (inblossom[base[tu]]){ base[tu]=newbase; if (!inqueue[tu]) q[++tail]=tu,inqueue[tu]=1; } } void FindAugmentingPath(){ memset(inqueue,0,sizeof (inqueue)); memset(father,0,sizeof (father)); for (int i=1;i<=n;i++) base[i]=i; head=1,tail=1;q[head]=start;inqueue[start]=1; finish=0; while (head<=tail){ int u=q[head++]; for (int v=1;v<=n;v++) if (G[u][v]&&(base[u]!=base[v])&&match[u]!=v){ if ((v==start)||(match[v]>0)&&(father[match[v]]>0)){ blossomcontract(u,v); }else if (father[v]==0){ father[v]=u; if (match[v]>0) q[++tail]=match[v],inqueue[match[v]]=1; else{ finish=v; return; } } } } } void AugmentPath(){ int u,v,w; u=finish; while (u>0){ v=father[u]; w=match[v]; match[v]=u; match[u]=v; u=w; } } void Edmonds(){ memset(match,0,sizeof match); for (int u=1;u<=n;u++) if (match[u]==0){ start=u; FindAugmentingPath(); if (finish>0) AugmentPath(); } } void Output(){ int cnt=0; for (int i=1;i<=n;i++) if (match[i]>0) cnt++; printf("%d\n",cnt); for (int i=1;i<=n;i++) if (i<match[i]) printf("%d %d\n",i,match[i]); } int main(){ init(); Edmonds(); Output(); return 0; }
相关文章推荐
- 农资产品送货车上使用 PDA手持机 现场销售开单 然后开单后能直接通过移动网络传回电脑(云服务器)
- 在CentOS 7上搭建lamp环境
- 35. Search Insert Position
- C++设计模式系列
- 杭电ACM--HDU-1061
- CodeForces 266C—— Below the Diagonal(模拟,贪心,递归)
- 正则表达式(一)
- 不等式 $x+\frac{1}{x} \ge 2$ 的无字证明
- 匿名内部类
- 用Jmeter进行压力测试
- 鸿洋Android 面试要点答案整理
- sourcetree 及git版本工具使用
- 嵌入式开发第7日(数组与指针)
- 程序员需要关注的那些网站(转自知乎)
- Sublime Text3 无法使用LiveReload插件的解决方法
- hdu 5171 GTY's birthday gift(矩阵快速幂,斐波那契)
- FZOJ1638求强连通分量
- Android常用--正则,广播和as快捷键
- Codeforces Round #205 (Div. 2)
- mongodb 主从复制