ACM乐园
Love Me,Love My Code!
posts - 53,  comments - 24,  trackbacks - 0
http://acm.hdu.edu.cn/showproblem.php?pid=1281
比较猎人打鸟问题,可以将车看做是子弹,每个车都有x,y坐标,可将其看做边,行数和列数看成是两个集合的点,该题就变为求最多的匹配边。

关键匹配就是指在保证最大匹配的前提下,不能缺少的匹配。也就是说如果缺少这对匹配,那么所求的匹配数不是最大匹配。
#include <iostream>

using namespace std;

const int M=101;
bool g[M][M];
bool visit[M];
int  link[M];
int  x[M*M],y[M*M];//记录匹配边,用于计算关键匹配
int  m,n,k;

bool find(int i)
{
    
int j;
    
for(j=1;j<=m;j++)
    {
        
if(g[i][j] && !visit[j])
        {
            visit[j]
=true;
            
if(link[j]==0 || find(link[j]))
            {
                link[j]
=i;
                
return true;
            }
        }
    }
    
return false;
}

int result()
{
    
int i,res=0;
    memset(link,
0,sizeof(link));//注意link数组要在这里做初始化,因为link数组要用多次
    for(i=1;i<=n;i++)
    {
        memset(visit,
0,sizeof(visit));
        
if(find(i))
            res
++;
    }
    
return res;
}

int main()
{
    
int t,l,c,count=0;
    
while(cin>>n>>m>>k)
    {
        count
++;
        memset(g,
0,sizeof(g));
        
for(t=0;t<k;t++)
        {
            cin
>>x[t]>>y[t];
            g[x[t]][y[t]]
=true;
        }
        l
=result();
        c
=0;
        
for(t=0;t<k;t++)        
        {
            g[x[t]][y[t]]
=false;//将(x[t],y[t])设为不连通,求最大匹配,如果变小,说明该边为关键匹配边
            if(result()<l)      
                c
++;
            g[x[t]][y[t]]
=true//还原状态
        }
        printf(
"Board %d have %d important blanks for %d chessmen.\n",count,c,l);
    }
    
return 0;
}


posted on 2011-09-14 00:24 大大木马 阅读(327) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2011年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(1)

随笔档案(53)

文章档案(2)

搜索

  •  

积分与排名

  • 积分 - 63780
  • 排名 - 351

最新评论

阅读排行榜

评论排行榜