POJ 3041 Asteroids 最小覆盖
题意很容易理解,读完题还是没想到用匈牙利算法,很神奇,怎么就跟最大匹配扯一块了呢
原来是最小覆盖问题 怎么看出的是最小覆盖 神奇之一 http://ip96cns.blog.163.com/blog/static/170095192201102452319234/
这几句话比较喜欢
这种把坐标上的点转化成图的线的方法,一种从坐标系到图的转化思想,值得记下来。
而其中的隐含关系是,坐标系的一行,一列,对应二分图上的两个点集,如此云云,博主已近乎疯狂。。。。。”
还有什么konning定理,最小覆盖=最大匹配数 神奇之二
代码就是一般的求最大匹配了 不神奇
贴之:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define nMAX 505 using namespace std; int map[nMAX][nMAX],link[nMAX]; bool vs[nMAX]; int n; bool dfs(int u) { for(int i=1;i<=n;i++) { if(!vs[i]&&map[u][i]) { vs[i]=1; if(!link[i]||dfs(link[i])) { link[i]=u; return 1; } } } return 0; } int MaxMatch() { int i,cnt=0; memset(link,0,sizeof(link)); for(i=1;i<=n;i++) { memset(vs,0,sizeof(vs)); if(dfs(i))cnt++; } return cnt; } int main() { int m,i,j; while(~scanf("%d%d",&n,&m)) { memset(map,0,sizeof(map)); while(m--) { scanf("%d%d",&i,&j); map[i][j]=1; } int ans=MaxMatch(); printf("%d\n",ans); } return 0; }
开始用自己不是方法的方法
现在还是觉得对,就是WA
贴个代码 以后找bug
//我就是感觉挺对的啊!!!老是WA #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; int cnt[1005],visit[502][502]; int cmp(const void * a,const void * b) { return *(int*)b-*(int*)a; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { int i,j,M,MM; M=m,MM=m; memset(cnt,0,sizeof(cnt)); memset(visit,0,sizeof(visit)); while(M--) { scanf("%d%d",&i,&j); visit[i-1][j-1]=1; cnt[i-1]++; cnt[j+n-1]++; } for(i=0;i<n;i++) for(j=0;j<n;j++) { if(!visit[i][j])continue; if(cnt[i]>1&&cnt[j+n]>1)MM++; } int ans=0; qsort(cnt,n*2,sizeof(cnt[0]),cmp); for(i=0;i<n*2;i++) { MM-=cnt[i]; ans++; if(MM==0)break; } printf("%d\n",ans); } return 0; }