hdu 1054 Strategic Game(模板) 最大二分匹配,最小点覆盖 匈牙利算法

来源:互联网 发布:飞客数据恢复怎么样 编辑:程序博客网 时间:2024/06/05 04:57

给定一图求最小点覆盖。

最大二分匹配=最小点覆盖

bfs版匈牙利算法

#include<cstdio>#include<cstring>#include<queue>#include<vector>using namespace std;const int maxn = 1550;struct edge{int from,to;};vector<int> g[maxn];vector<edge> edges;int n;int check[maxn],match[maxn],pre[maxn];void addedge(int from,int to){edges.push_back(edge{from,to});edges.push_back(edge{to,from});int m=edges.size();g[from].push_back(m-2);g[to].push_back(m-1);}int Hungarian(){int ans=0;memset(match,-1,sizeof(match));memset(check,-1,sizeof(check));for(int i=0;i<n;i++){queue<int> q;if(match[i]==-1){q.push(i);pre[i]=-1;bool flag=false;while(!q.empty()&&!flag){int u=q.front();for(int j=0;j<g[u].size()&&!flag;j++){edge &e=edges[g[u][j]];int v=e.to;if(check[v]!=i){check[v]=i;q.push(match[v]);if(match[v]>=0)pre[match[v]]=u;else{flag=1;int d=u,e=v;while(d!=-1){int t=match[d];match[d]=e;match[e]=d;d=pre[d];e=t;}}}}q.pop();}if(match[i]!=-1)ans++;}}return ans;}int main(){//freopen("in.txt","r",stdin);while(scanf("%d",&n)!=EOF){int u,num,v;for(int i=0;i<=n;i++)g[i].clear();edges.clear();for(int i=0;i<n;i++){scanf("%d:(%d)",&u,&num);while(num--){scanf("%d",&v);addedge(u,v);}}int ans=Hungarian();printf("%d\n",ans);}}
dfs版本
#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;const int maxn = 1505;struct edge{int from,to;};vector<edge> edges;vector<int> g[maxn];int check[maxn],match[maxn];int n;void addedge(int from,int to){edges.push_back(edge{from,to});edges.push_back(edge{to,from});int m=edges.size();g[from].push_back(m-2);g[to].push_back(m-1);}bool dfs(int u){for(int i=0;i<g[u].size();i++){int v=edges[g[u][i]].to;if(!check[v]){check[v]=1;if(match[v]==-1||dfs(match[v])){match[v]=u;match[u]=v;return true;}}}return false;}int Hungarian(){int ans=0;memset(match,-1,sizeof(match));for(int i=0;i<n;i++){if(match[i]==-1){memset(check,0,sizeof(check));if(dfs(i))++ans;}}return ans;}int main(){//freopen("in.txt","r",stdin);while(scanf("%d",&n)!=EOF){int u,num,v;edges.clear();for(int i=0;i<n;i++)g[i].clear();for(int i=0;i<n;i++){scanf("%d:(%d)",&u,&num);while(num--){scanf("%d",&v);addedge(u,v);}}int ans;ans=Hungarian();printf("%d\n",ans);}}

0 0
原创粉丝点击