syhd142  
日历
<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
统计
  • 随笔 - 23
  • 文章 - 122
  • 评论 - 31
  • 引用 - 0

导航

常用链接

留言簿(2)

随笔档案(23)

文章分类(270)

文章档案(122)

我的豆瓣

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
很久没有A题了,最近恢复训练,找回旧日的激情。拿几个图论题目练练手。
解法:很裸的KM最大权匹配,好久没敲了,有点忘记了。
#include <stdio.h>
#include 
<stdlib.h>
#include 
<string.h>

#define N 105
#define INF 1 << 29
#define MAX(a, b) (a > b ? a : b)
#define MIN(a, b) (a > b ? b : a)

int g[N][N], lx[N], ly[N], match[N];
bool x[N], y[N];

bool dfs(int u, int n)
{
    x[u] 
= 1;
    
for(int i = 1; i <= n; i++)
    {
        
int wt = lx[u] + ly[i] - g[u][i];
        
if(!y[i] && !wt)
        {
            y[i] 
= 1;
            
if(match[i] == -1 || dfs(match[i], n))
            {
                match[i] 
= u;
                
return 1;
            }
        }
    }
    
return 0;
}

int KM(int n)
{
    memset(ly, 
0sizeof(ly));
    memset(match, 
-1sizeof(match));
    
for(int i = 1; i <= n; i++)
    {
        lx[i] 
= -INF;
        
for(int j = 1; j <= n; j++)
        {
            lx[i] 
= MAX(lx[i], g[i][j]);
        }
    }
    
for(int k = 1; k <= n; k++)
    {
        memset(x, 
0sizeof(x));
        memset(y, 
0sizeof(y));
        
while(!dfs(k, n))
        {
            
int d = INF;
            
for(int i = 1; i <= n; i++)
                
if(x[i])
                    
for(int j = 1; j <= n; j++)
                        
if(!y[j])
                            d 
= MIN(d, lx[i] + ly[j] - g[i][j]);
            
for(int i = 1; i <= n; i++)
            {
                
if(x[i]) lx[i] -= d, x[i] = 0;
                
if(y[i]) ly[i] += d, y[i] = 0;
            }
        }
    }
    
int sum = 0;
    
for(int i = 1; i <= n; i++)
        sum 
+= g[match[i]][i];
    
return sum;
}


int main()
{
    
int n, v[N], ans;
    
char str[N];
    
while(scanf("%d"&n), n)
    {
        memset(g, 
0sizeof(g));
        
for(int i = 1; i <= n; i++)
            scanf(
"%d"&v[i]);
        
for(int i = 1; i <= n; i++)
        {
            scanf(
"%s"&str);
            
for(int j = 0; j < n; j++)
            {
                
if('1' == str[j])
                {
                    g[i][j 
+ 1= v[i] ^ v[j + 1];
                }
            }
        }
        ans 
= KM(n);
        printf(
"%d\n", ans);
    }
    
return 0;
}


posted on 2010-05-20 10:32 Fucker 阅读(233) 评论(0)  编辑 收藏 引用 所属分类: ACM/ICPC

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


 
Copyright © Fucker Powered by: 博客园 模板提供:沪江博客