题目链接:传送门
题目大意:有k个任务,可以在 A 机器的 x 位上完成,也可以在 B 机器的 y 位上完成。问最少需要多少个点位即可完成所有任务。
题目思路:求最小点覆盖。
把 A 机器,B 机器看做两个集合,任务需要的点位即可看做 A,B 之间的边,要最少点位,也就是要最少的点覆盖完所有的边。
二分图匹配即可(二分图 最小点覆盖==最大匹配数)
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <cctype> #include <queue> #include <string> #include <vector> #include <set> #include <map> #include <climits> #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define fi first #define se second #define ping(x,y) ((x-y)*(x-y)) #define mst(x,y) memset(x,y,sizeof(x)) #define mcp(x,y) memcpy(x,y,sizeof(y)) using namespace std; #define gamma 0.5772156649015328606065120 #define MOD 1000000007 #define inf 0x3f3f3f3f #define N 1505 #define maxn 500005 typedef pair<int,int> PII; typedef long long LL; int n,k,m,ans,S,T,hcnt; int pic[202][202]; int vis[202],lik[202]; int dfs(int x){ for(int i=1;i<=m;++i){ if(pic[x][i]&&!vis[i]){ vis[i]=1; if(lik[i]==-1||dfs(lik[i])){ lik[i]=x; return 1; } } } return 0; } void xyl(){ mst(lik,-1); for(int i=1;i<=n;++i){ mst(vis,0); ans+=dfs(i); } } int main(){ int i,j,group,x,y,v,id; while(scanf("%d",&n)!=EOF&&n){ mst(pic,0); scanf("%d%d",&m,&k); for(i=1;i<=k;++i){ scanf("%d%d%d",&v,&x,&y); pic[x][y]=1; } ans=0; xyl(); printf("%d\n",ans); } return 0; }
时间: 2024-11-29 09:57:10