程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Antenna Placement poj3020

Antenna Placement poj3020

編輯:C++入門知識

  這是一道比較經典的二分匹配,將格子按黑白標記後,再將含'*'的格子按黑白分成兩組,建邊。最後的結果就是總的'*'的個數-匹配數。

[cpp] 
#include<iostream> 
#include<cstdio> 
#include<vector> 
using namespace std; 
vector<int>map[400];//按奇偶性建二分圖  
int t,n,m; 
int match[400],fy[400],ln,rn;  
int map1[41][11];//原始圖  
int dirt[4][2]={0,1,0,-1,1,0,-1,0}; 
 
int path(int u) 

    for(int i=0,j;i<map[u].size();i++) 
    { 
        j=map[u][i]; 
        if(!fy[j]) 
        { 
            fy[j]=1; 
            if(match[j]==-1||path(match[j])) 
            { 
                match[j]=u; 
                return 1; 
            } 
        } 
    } 
    return 0; 

 
int main() 

    int i,j,x,y,ans; 
    char tmp; 
    scanf("%d",&t); 
    while(t--) 
    { 
        scanf("%d%d",&n,&m); 
        ln=rn=0; 
        for(i=1;i<=n;i++) 
        { 
            getchar(); 
            for(j=1;j<=m;j++) 
            { 
                scanf("%c",&tmp); 
                if(tmp=='*') 
                { 
                    if((i+j)&1)//奇點  
                        map1[i][j]=++ln; 
                    else//偶點  
                        map1[i][j]=++rn; 
                } 
                else 
                    map1[i][j]=0; 
            } 
        } 
        for(i=1;i<=ln;i++) 
            map[i].clear(); 
        for(i=1;i<=rn;i++) 
            match[i]=-1; 
             
        //建二分圖  
        for(i=1;i<=n;i++) 
            for(j=1;j<=m;j++) 
            { 
                if(!map1[i][j]||!((i+j)&1)) 
                    continue; 
                for(int k=0;k<4;k++) 
                { 
                    x=i+dirt[k][0]; 
                    y=j+dirt[k][1]; 
                    if(x<=0||x>n||y<=0||y>m||!map1[x][y]) 
                        continue; 
                    map[map1[i][j]].push_back(map1[x][y]); 
                } 
            } 
             
        //求最大匹配  
        ans=0; 
        for(i=1;i<=ln;i++) 
        { 
            for(j=1;j<=rn;j++) 
                fy[j]=0; 
            if(path(i)) 
                    ans++; 
        } 
        printf("%d\n",ln+rn-ans); 
    } 
    return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved