poj 2195  最优匹配算法的优化

来源:互联网 发布:淘宝运送方式怎么设置 编辑:程序博客网 时间:2024/05/29 14:28
最优匹配算法:
通过构造每个点的顶标 , 来得到最优匹配 , 在普通的算法中 , 时间复杂度为O(n^4) , 我们可以通过改善改变顶标的的算法 ,可以优化到O(n^3) 。

对于改变顶标 , 我们可以在寻找增广路时 , 改变顶标 。

代码:总权值最小的最优匹配

bool match(int i)  // 寻找增广路
{
    s[i] =true;
    for(int j =1; j <= n; j++)
    {
      
       if(lx[i]+ly[j] == w[i][j] && !t[j])
       {
         
           t[j] = true;
           if(!pre[j] || match(pre[j]))
           {
               pre[j] = i;
             tr[i] =w[i][j];
               return true;
           }
       }
      else   slack[j] = min(slack[j] ,w[i][j]-lx[i]-ly[j]);  //同时更新每个点的最小差值
    }
    returnfalse;
}


void km()
{
    int i ,j;
    for(i = 1; i<= n; i++)
    {
       pre[i] = ly[i] =0;   //  构造可行顶标
       lx[i] =INF;
       for(j = 1; j <= n; j++)
           lx[i] = min(lx[i] , w[i][j]);
      
    }
   
    for(i = 1; i<= n; i++)
    {
       for(; ; )
       {
           for(j = 1; j <= n; j++)  s[j] = t[j] = 0 ,slack[j] = INF;  //初始化x和y中点的状态

           if(match(i)) break; // 寻找增广路
          
   
          int a =INF;  //修改顶标
          for(j = 1; j<= n; j++)
            if(!t[j])
                a = min(a ,slack[j]);
      
          for(j = 1; j<= n; j++)
          {
            if(s[j])  lx[j] += a;
            if(t[j])  ly[j] -= a;
          }
       }
    }
}
0 0