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;
}

  

posted @ 2012-02-03 02:31  快乐.  阅读(212)  评论(0编辑  收藏  举报