本文主要是介绍poj 3041 Asteroids 二分匹配 匈牙利算法 模板题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
http://poj.org/problem?id=3041
题意:给你长宽都有n个格子的矩阵,其中一些格子放着星球,现在可以一次 消除 一行或者一列的星球
求要让所有星球都消失的最少的次数。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
int max(int a,int b) {return a>b?a:b;};
int min(int a,int b) {return a<b?a:b;};
const int N = 500;
const int M=20000;
int n,m,x,y;
vector<int> G[1005];
int used[505],match[1005];
void add_edge(int u,int v)
{
G[u].push_back(v);
G[v].push_back(u);
}
int dfs(int u)
{
used[u]=1;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i],w=match[v];
if(w<0||!used[w]&&dfs(w))
{
match[u]=v;
match[v]=u;
return 1;
}
}
return 0;
}
int max_flow()
{
memset(match,-1,sizeof(match));
int ans=0;
for(int u=1;u<=n;u++)
if(match[u]<0)
{
memset(used,0,sizeof(used));
if(dfs(u))
ans++;
}
return ans;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
for(int i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
add_edge(x,y+n);
}
printf("%d\n",max_flow());
}
return 0;
}
分析:构造二分图,左边一列是星球的行,右边一列是星球的列 ,则放入一个星球就转化成了一条边,
则最小顶点覆盖=>最大匹配,然后匈牙利算法
找增广路
【传说】99北极-老活 2016/2/10 23:47:02
是从一边开始
【传说】99北极-老活 2016/2/10 23:47:13
所以是左边或者右边点的数量
【传说】99北极-老活 2016/2/10 23:47:27
不是总点数
【传说】99北极-老活 2016/2/10 23:47:39
另外左右边点数可以不一样
【传说】99北极-老活 2016/2/10 23:47:02
是从一边开始
【传说】99北极-老活 2016/2/10 23:47:13
所以是左边或者右边点的数量
【传说】99北极-老活 2016/2/10 23:47:27
不是总点数
【传说】99北极-老活 2016/2/10 23:47:39
另外左右边点数可以不一样
这篇关于poj 3041 Asteroids 二分匹配 匈牙利算法 模板题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!