poj 1325 最小点覆盖

本来今天晚上想去自习的,然后想起好多天没怎么好好刷题了,然后就想晚上写个最大流的算法,然后回宿舍就变成写最大匹配,然后是最小点覆盖,一点也没有扯上最大流的。。。

最小点覆盖=最大匹配,是个定理,证明没有怎么看懂的,只是会用~

题目大意:有两台机器,分别有n和m种模式,有k个任务,每个任务可以在a和b机器中的一个模式下运行,每次机器进入一个模式都要重启,让你求最少的重启次数。刚开始的时候两台机器都处于0模式下。

解题思路:一开始没有看懂题~,然后就是建立二分图,求覆盖所有边的最小的点数,即为最小点覆盖,可以直接贴模板的,只是要多注意细节的!

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
using namespace std;
#define rep(i,n) for(int i=0; i<n; i++)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#define fab(a) ((a)>0?(a):(0-(a)))
#define ll long long
#define arc(a) ((a)*(a))
#define inf 100000
#define exp 0.000001
#define N 100
int n,m,k;
vector<int>q[N+5];
bool vis[N+5];
int next[N+5];
bool find(int t)
{
    for(int i=0; i<q[t].size(); ++i)
	{
		int m=q[t][i];
		if(vis[m]==false)
		{
			vis[m]=true;
			if(next[m]==-1|| find(next[m])){
				next[m]=t;
				return true;
			}
		}
	}
	return false;
}
void sum()
{
	int suml=0;
	memset(next,-1,sizeof(next));
	repf(i,1,n-1)
	{
		memset(vis,false,sizeof(vis));
		if(find(i))
			suml++;
	}
	printf("%d\n",suml);
}
int main()
{
	int x,y,z;
	while(scanf("%d",&n)&& n){
		scanf("%d%d",&m,&k);
		rep(i,n)
			q[i].clear();
		rep(i,k){
			scanf("%d%d%d",&x,&y,&z);
			if(z!=0)
			q[y].push_back(z);
		}
		sum();
	}
	return 0;
}
  


你可能感兴趣的:(poj 1325 最小点覆盖)