POJ 2400 KM

http://poj.org/problem?id=2400

题意:N个领导对N个员工排名(排在最前面的分数为0,表示评价最高),同时N个员工对N个领导排名,原则同上

求 每个人平均分最少 

题目输入足够把人绕晕。。。

还要求把所有的情况输出,用dfs找所有的情况 我做这个题为了熟悉KM

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define Max(a,b)a>b?a:b
#define Min(a,b)a<b?a:b
#define MAX 18
#define inf 9999999
using namespace std;
int lx[MAX],ly[MAX],map[MAX][MAX],link[MAX];
bool vx[MAX],vy[MAX];
int n,m,ans,cnt;

bool dfs(int u)
{
    int j;
    vx[u]=1;
    for(j=1;j<=m;j++)
        if(!vy[j]&&map[u][j]==lx[u]+ly[j])//map[u][j]==vx[u]+vy[j]妹的!
        {
            vy[j]=1;
            if(!link[j]||dfs(link[j]))
            {
                link[j]=u;
                return true;
            }
        }
    return false;
}

int KM()
{

    int i,j,k,mi;
    for(i=1;i<=n;i++)
        for(lx[i]=-inf,j=1;j<=m;j++)
          lx[i]=Max(lx[i],map[i][j]);
    memset(ly,0,sizeof(ly));

    memset(link,0,sizeof(link));
    for(i=1;i<=n;i++)
    {
        while(1)
        {   memset(vx,0,sizeof(vx));
            memset(vy,0,sizeof(vy));
            if(dfs(i))break;

            mi=inf;
            for(j=1;j<=n;j++)
              if(vx[j])
               for(k=1;k<=m;k++)
                if(!vy[k])
                  mi=Min(mi,lx[j]+ly[k]-map[j][k]);
            for(j=1;j<=n;j++)if(vx[j])lx[j]-=mi;
            for(j=1;j<=m;j++)if(vy[j])ly[j]+=mi;
        }
    }
    ans=0;
    for(i=1;i<=m;i++)
      if(link[i])ans-=map[link[i]][i];
    return ans;
}

void OutDfs(int dep,int Sum)
{
    int i;
    if(Sum>ans)return ;
    if(dep>n)
    {
        if(Sum!=ans)return ;
        printf("Best Pairing %d\n",++cnt);
        for(i=1;i<=m;i++)
        printf("Supervisor %d with Employee %d\n",i,link[i]);
    }
    else
    {
        for(i=1;i<=m;i++)
            if(!vy[i])
            {
              vy[i]=1;
              link[dep]=i;//??
              OutDfs(dep+1,Sum-map[dep][i]);
              vy[i]=0;
            }
    }
}

int main()
{
   int CASE,ca,i,j,k;
   scanf("%d",&CASE);
   for(ca=1;ca<=CASE;ca++)
   {
       memset(map,0,sizeof(map));
       scanf("%d",&n);
       m=n;
       for(i=1;i<=n;i++)
          for(j=0;j<m;j++)
          {
              scanf("%d",&k);
              map[k][i]-=j;
          }
      for(i=1;i<=n;i++)
         for(j=0;j<n;j++)
         {
             scanf("%d",&k);
             map[i][k]-=j;
         }

         printf("Data Set %d, Best average difference: %.6f\n",ca,0.5*KM()/n);

         cnt=0;
         memset(vy,0,sizeof(vy));
         OutDfs(1,0);
         printf("\n");
   }
   return 0;
}

  

posted @ 2012-02-14 03:07  快乐.  阅读(243)  评论(0)    收藏  举报