LightOJ
来源:互联网 发布:innerhtml js不执行 编辑:程序博客网 时间:2024/06/03 09:07
匈牙利算法
#include<cstdio>#include<cstring>#include<cmath>#include<vector>using namespace std;/*求二分图的最大独立集邻接表存图匈牙利算法得到最大匹配(或最小顶点覆盖)hungary()V-hungary()=最大独立集*/const int maxn=4e4+5;//点的最大值const int maxm=5e5+5;int n;int a[maxn],b[maxm];int factor[maxn];// 质因数vector<int>G[maxn];//二分图int linker[maxn];bool used[maxn];bool dfs(int u){ for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) { linker[v]=u; return true; } } } return false;}//最大匹配int hungary(){ int res=0; for(int u=1;u<=n;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res;}void init(){ memset(linker,-1,sizeof(linker)); memset(b,0,sizeof(b)); for(int i=1;i<=n;i++) { G[i].clear(); }}int main(){ int T,t; scanf("%d",&T); for(int kase=1;kase<=T;kase++) { init(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=n;i++) { b[a[i]]=i;//对结点hash } for(int i=1;i<=n;i++) { t=a[i]; int cnt=0,sum=0;//分解质因子 //cnt为质因数个数,sum为质因数总数 for(int j=2;t>1&&j<=sqrt(t);j++) { if(t%j==0) { factor[cnt++]=j; while(t%j==0) { t=t/j; sum++; } } } if(t>1)//如果t为质数 { factor[cnt++]=t; sum++; } for(int j=0;j<cnt;j++) { t=b[ a[i]/factor[j] ]; if(t==0)//不存在对应关系 { continue; } if(sum&1)////共有奇数个质因子 { G[i].push_back(t); } else////共有偶数个质因子 { G[t].push_back(i); } } } printf("Case %d: %d\n",kase,n-hungary()); } return 0;}
Hopcroft-Karp算法
#include<cstdio>#include<cstring>#include<cmath>#include<queue>using namespace std;/*求二分图的最大独立集邻接表存图Hopcroft-Karp算法得到最大匹配(或最小顶点覆盖)MaxMatch()V-MaxMatch()=最大独立集*/#define INF 0x3f3f3f3fconst int maxn=4e4+5;//点的最大值const int maxm=5e5+5;int n;int a[maxn],b[maxm];int factor[maxn];//质因数vector<int>G[maxn];//二分图int Mx[maxn],My[maxn];int dx[maxn],dy[maxn];int dis;bool used[maxn];bool SearchP(){ queue<int>Q; dis=INF; memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); for(int i=1;i<=n;i++) { if(Mx[i]==-1) { Q.push(i); dx[i]=0; } } while(!Q.empty()) { int u=Q.front(); Q.pop(); if(dx[u]>dis) break; int sz=G[u].size(); for(int i=0;i<sz;i++) { int v=G[u][i]; if(dy[v]==-1) { dy[v]=dx[u]+1; if(My[v]==-1) { dis=dy[v]; } else { dx[My[v]]=dy[v]+1; Q.push(My[v]); } } } } return dis!=INF;}bool DFS(int u){ int sz=G[u].size(); for(int i=0;i<sz;i++) { int v=G[u][i]; if(!used[v]&&dy[v]==dx[u]+1) { used[v]=1; if(My[v]!=-1&&dy[v]==dis) continue; if(My[v]==-1||DFS(My[v])) { My[v]=u; Mx[u]=v; return 1; } } } return 0;}//最大匹配int MaxMatch(){ int res=0; memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My)); while(SearchP()) { memset(used,0,sizeof(used)); //点的编号[1,n] for(int i=1;i<=n;i++) { if(Mx[i]==-1&&DFS(i)) { res++; } } } return res;}void init(){ memset(b,0,sizeof(b)); for(int i=1;i<=n;i++) { G[i].clear(); }}int main(){ int T,t; scanf("%d",&T); for(int kase=1;kase<=T;kase++) { init();//清空 scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=n;i++) { b[a[i]]=i;//对结点hash } for(int i=1;i<=n;i++) { t=a[i]; int cnt=0,sum=0;//分解质因子 //cnt为质因数个数,sum为质因数总数 for(int j=2;t>1&&j<=sqrt(t);j++) { if(t%j==0) { factor[cnt++]=j; while(t%j==0) { t=t/j; sum++; } } } if(t>1)//如果t为质数 { factor[cnt++]=t; sum++; } for(int j=0;j<cnt;j++) { t=b[ a[i]/factor[j] ]; //printf("t=%d a=%d factor=%d\n",t,a[i],factor[j]); if(t==0)//不存在对应关系 { continue; } if(sum&1)//共有奇数个质因子 { G[i].push_back(t); //printf("1 i=%d t=%d\n",i,t); } else//共有偶数个质因子 { G[t].push_back(i); //printf("2 t=%d i=%d\n",t,i); } } } printf("Case %d: %d\n",kase,n-MaxMatch()); } return 0;}
阅读全文
0 0
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- [LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- kafka无法正常生产消费,但依旧可以创建生产者和消费者
- Quartz Cron表达式 每周、每月执行一次
- 代码中特殊的注释技术——TODO、FIXME和XXX的用处
- php中查询数据库含通配符时需要转义的问题
- C++实践积累
- LightOJ
- Linux下修改Mysql数据库存放路径
- Windows下Android app压力测试学习笔记
- 2017暑期集训Day 9 递推
- Unity3D 海水多线程渲染算法实现
- 文章不错记录一下
- Jquery加强
- namespace的理解
- VS2013安装失败(win8.1)