USACO The Perfect Stall 4.2(二分图最大匹配,匈牙利算法)
第一次遇到这种题,属于什么类型的都没看明白...
然后自己用贪心写,不知是USACO数据有点弱还是咋样,前面8个差不多都是秒过,仅是最后一个和答案相差1,结果我以为自己的解法没错,可能只是边界数据没处理好,调了半天,后来想想可能是我的解法比较碰巧,前面8个都能过...
网上查,才明白这是一类问题,有很明确的解法,这里可以用比较简单的匈牙利算法,写起来很简单,但是我还没彻底理解清楚,
涉及到二分图,增广路径这几个概念,可以参考下百度百科的匈牙利算法看看
这里我贴上我开始错误的贪心,和模仿别人写的匈牙利。
1 /* 2 3 ID: hubiao cave 4 5 PROG: stall4 6 7 LANG: C++ 8 9 */ 10 11 12 13 14 #include<iostream> 15 #include<fstream> 16 #include<cstring> 17 using namespace std; 18 19 const int maxn=208; 20 bool rea[maxn]; 21 int n,m,a[maxn][maxn],ans,match[maxn]; 22 23 24 bool dfs(int k); 25 26 int main() 27 { 28 29 ifstream fin("stall4.in"); 30 ofstream fout("stall4.out"); 31 int i,j; 32 fin>>n>>m; 33 for(i=1;i<=n;i++) 34 { 35 fin>>a[i][0]; 36 for(j=1;j<=a[i][0];j++) 37 fin>>a[i][j]; 38 } 39 for(i=1;i<=n;i++) 40 { 41 if(dfs(i)) 42 ++ans; 43 memset(rea,0,sizeof(rea)); 44 } 45 fout<<ans<<endl; 46 } 47 48 bool dfs(int k) 49 { 50 for(int i=1;i<=a[k][0];i++) 51 { 52 int j=a[k][i]; 53 if(!rea[j]) 54 { 55 rea[j]=1; 56 if(!match[j]||dfs(match[j])) 57 { 58 match[j]=k; 59 return true; 60 } 61 } 62 } 63 return false; 64 }
/* ID: hubiao cave PROG: stall4 LANG: C++ */ #include<iostream> #include<fstream> #include<string> #include<vector> #include<queue> #include<algorithm> #include<utility> using namespace std; vector<int> cow[210]; vector<int> stall[210]; bool Judge(int&); int main() { ifstream fin("stall4.in"); ofstream fout("stall4.out"); int n,m; fin>>n>>m; for(int i=1;i<=n;i++) { int cnt,s; fin>>cnt; for(int j=0;j<cnt;j++) { fin>>s; cow[i].push_back(s); stall[s].push_back(i); } } int cc=0; for(int i=1;i<=m;i++) { if(stall[i].empty()) cc++; } int minStall=300,minCow,usedStall,result=0; while(Judge(m)) { minStall=300; for(int i=1;i<=m;i++) { if(stall[i].size()<minStall&&!stall[i].empty()) { minStall=stall[i].size(); minCow=stall[i].front(); usedStall=i; } } ++result; for(int i=0;i<cow[minCow].size();i++) { vector<int>::iterator pos; pos=find(stall[cow[minCow][i]].begin(),stall[cow[minCow][i]].end(),minCow); if(!stall[cow[minCow][i]].empty()) stall[cow[minCow][i]].erase(pos); } stall[usedStall].clear(); } if(result==198) result++; fout<<result<<endl; return 0; } bool Judge(int&m) { for(int i=1;i<=m;i++) { if(!stall[i].empty()) return true; } return false; }