标签:
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27475
【思路】
二分图的最小点覆盖以及构造最小覆盖。
可见:http://www.tuicool.com/articles/jmAnEb
【代码】
#include<cstdio> #include<cstring> #include<vector> #include<iostream> using namespace std; const int maxn = 1000+10; bool S[maxn],T[maxn]; int lky[maxn],lkx[maxn]; vector<int> G[maxn]; bool match(int u) { S[u]=1; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!T[v]) { T[v]=1; if(!lky[v] || match(lky[v])) { lky[v]=u , lkx[u]=v; return true; } } } return false; } int n,m,k; void read(int& x) { char c=getchar(); while(!isdigit(c)) c=getchar(); x=0; while(isdigit(c)) { x=x*10+c-‘0‘ , c=getchar(); } } int main() { while(scanf("%d%d%d",&n,&m,&k)==3 &&(n)) { for(int i=1;i<=n;i++) G[i].clear(); int u,v; for(int i=0;i<k;i++) { read(u),read(v); G[u].push_back(v); } memset(lky,0,sizeof(lky)); memset(lkx,0,sizeof(lkx)); int ans=0; for(int i=1;i<=n;i++) { memset(T,0,sizeof(T)); memset(S,0,sizeof(S)); if(match(i)) ans++; } printf("%d ",ans); memset(S,0,sizeof(S)); memset(T,0,sizeof(T)); for(int i=1;i<=n;i++) if(!lkx[i]) match(i); for(int i=1;i<=n;i++) if(!S[i]) printf("r%d ",i); for(int i=1;i<=n;i++) if(T[i]) printf("c%d ",i); putchar(‘\n‘); } return 0; }
标签:
原文地址:http://www.cnblogs.com/lidaxin/p/5077066.html