您的位置:首页 > 其它

pku1325(二分图最小覆盖)

2010-09-04 20:53 363 查看
http://162.105.81.212/JudgeOnline/problem?id=1325

题意:有两台机器A、B,一台有n种模式,一台有m种模式,有k个任务,每个任务都可以用A的某个模式或B的某个模式完成,开始两机器均为0模式,问最少切换多少次模式可完成所有任务。

思路:两台机器的模式可理解为两个集合,每个任务可理解为连接两种模式的线,则该问题可转换为二分图问题,即拿出多少个点可以消除所有的线,就是求二分图的最小点覆盖数,由于有最小点覆盖数等于最大匹配数,因此只需要用匈牙利算法求出最大匹配数即可。

#include<iostream>
using namespace std;
#define maxn 1000
int N, M, uN;
bool g[maxn][maxn];
int xM[maxn], yM[maxn];
bool chk[maxn];
bool find(int u)
{
int v;
for(v=1; v<=M; v++)		//B工线的数量M,
if(g[u][v] && !chk[v])
{
chk[v] = true;
if(yM[v] == -1 || find(yM[v]))
{
yM[v] = u;
xM[u] = v;
return true;
}
}
return false;
}
int MaxMatch()
{
int u, ret = 0;
memset(xM, -1, sizeof(xM));
memset(yM, -1, sizeof(yM));
for(u= 1;u<=N; u++)		//A工线的数量N;
{
if(xM[u] == -1)
{
memset(chk, false, sizeof(chk));
if(find(u)) ret++;
}
}
return ret;
}
int main()
{
int i, id, k, x, y, res;
while(scanf("%d%d%d",&N, &M, &k) && N)
{
memset(g, 0, sizeof(g));
for(i=0; i<k; i++)
{
scanf("%d%d%d",&id, &x, &y);
//if(x * y != 0)		//因为都是从0号开始的所有要这么构图,但是不用也能AC
g[x][y] = 1;
}
res = MaxMatch();
printf("%d/n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: