POJ 3020 Antenna Placement (Hungary)

来源:互联网 发布:微软excel 软件下载 编辑:程序博客网 时间:2024/05/01 08:32

 求最小覆盖边,

 无向二分图的最小路径覆盖 = 顶点数 – 最大二分匹配数/2

 由于构图过程中匹配双向的,所以匹配数多了一倍,最后要/2

 构图可以用奇偶,或者用数来标记

//#pragma comment(linker, "/STACK:102400000,102400000")#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>using namespace std;typedef long long LL;const long long mod = 1e9 + 7;const int INF = 0x3f3f3f3f;//const int M = 305;struct node{    int s,t,nxt ;} e[5000] ;int m,n,head[405],cnt,match[405],vis[405];int find(int s){    for(int i=head[s] ; i!=-1 ; i=e[i].nxt)    {        int tt=e[i].t ;        if(!vis[tt])        {            vis[tt]=1 ;            if(match[tt]==-1 || find(match[tt]))            {                match[tt]=s ;                return 1 ;            }        }    }    return 0 ;}int max_match(){    int ans=0 ;    memset(match,-1,sizeof(match)) ;    for(int i=1 ; i<=m ; i++)    {        memset(vis,0,sizeof(vis)) ;        ans+=find(i);    }    return ans;}void add(int s,int t){    e[cnt].s=s ;    e[cnt].t=t ;    e[cnt].nxt=head[s] ;    head[s]=cnt++ ;}//char M[405][405] ;int mp[455][455] ;int dx[]= {1,-1,0,0} ;int dy[]= {0,0,1,-1} ;int main(){    int T ;    scanf("%d",&T) ;    while(T--)    {        int N,M;        scanf("%d%d",&N,&M) ;        n=0 ;        char tmp;        memset(mp,0,sizeof(mp)) ;        for(int i=0 ; i<N ; i++)        {            for(int j=0 ; j<M ; j++)            {                cin>>tmp;                if(tmp=='*')                {                    mp[i][j]=++n;                }                       //也可以用奇偶数建图//                if(tmp=='*')//                {//                    if((i+j)&1)//奇点//                        mp[i][j]=++ln;//                    else//偶点//                        mp[i][j]=++rn;//                }//                else//                    mp[i][j]=0;            }        }        memset(head,-1,sizeof(head)) ;        cnt=0 ;        for(int i=0 ; i<N ; i++)        {            for(int j=0 ; j<M ; j++)            {                if(mp[i][j])                {                    for(int k=0 ; k<4 ; k++)                    {                        int xx=i+dx[k] ;                        int yy=j+dy[k] ;                        if(xx<0 || xx>=N || yy<0 || yy>=M || !mp[xx][yy])                            continue ;                        if(mp[xx][yy])                        {                            add(mp[i][j],mp[xx][yy]) ;                        }                    }                }            }        }        m=n ;        printf("%d\n",n-max_match()/2) ;    }    return 0 ;}

0 0
原创粉丝点击