OpenJ_POJ

来源:互联网 发布:vb登陆修改密码代码 编辑:程序博客网 时间:2024/05/15 03:07

题意:给出一个二分图,求最大匹配,并将对些边输出

思路:这题的建立二分图和男女关系那题建图类似

点击打开链接

但是此题的数据非常非常大,普通的匈牙利算法,复杂度O(ve)会超时!!!

所以要用高端的Hopcroft_Carp算法,复杂度O(sqrt(n)*e)!!

TLE了半天 ,无语。

以下借鉴kuangbin的模板!

#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<queue>using namespace std;const int maxn=100005;const int inf=0x3f3f3f3f;vector<int >g[maxn];int un;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<=un;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]=true;if(my[v]!=-1&&dy[v]==dis)continue;if(my[v]==-1||dfs(my[v])){my[v]=u;mx[u]=v;return true;}}}return false;}int maxmatch(){int res=0;memset(mx,-1,sizeof mx);memset(my,-1,sizeof my);while(searchp()){memset(used,false,sizeof used);for(int i=1;i<=un;i++){if(mx[i]==-1&&dfs(i)){res++;}}}return res;}bool  vis[maxn];int main(){int n,m;int a,b;scanf("%d%d",&n,&m);memset(vis,false,sizeof vis);un=n;for(int i=0;i<m;i++){scanf("%d%d",&a,&b);g[a].push_back(b);g[b].push_back(a);}maxmatch();for(int i=1;i<=n;i++){if(!vis[i]&&!vis[my[i]]){vis[i]=vis[my[i]]=true;printf("%d %d\n",i,my[i]);}}return 0;}


原创粉丝点击