KM算法模版

 1 #include<iostream>
 2 #include<cstring>
 3 #define N 500
 4 using namespace std;
 5 
 6 int n,w[N][N];
 7 int lx[N],ly[N],f[N];bool vx[N],vy[N];
 8 
 9 int Search(int k){
10     vx[k]=1;
11     
12     for(int i=1;i<=n;++i)
13     if(!vy[i]&&lx[k]+ly[i]==w[k][i])
14     {
15       if(f[i]==-1||Search(f[i]))
16       {f[i]=k;return 1;}       
17                                     }
18     return 0;
19     }
20 
21 long KM(int p){
22      if(!p)
23      {
24        for(int i=1;i<=n;++i)
25        for(int j=1;j<=n;++j)
26        w[i][j]=-w[i][j];
27            }
28      
29      for(int i=1;i<=n;++i)
30      {
31        lx[i]=-100000000;
32        for(int j=1;j<=n;++j)
33        if(lx[i]<w[i][j]) lx[i]=w[i][j];    
34        ly[i]=0;
35              }
36      
37      memset(f,-1,sizeof(f));
38      for(int i=1;i<=n;++i)
39      {
40        while(1)
41        {
42          memset(vx,0,sizeof(vx));
43          memset(vy,0,sizeof(vy));
44          
45          if(Search(i)) break;
46          
47          int mi=100000000;
48          for(int j=1;j<=n;++j)
49          if(vx[j])
50          for(int k=1;k<=n;++k)
51          if(!vy[k]&&lx[j]+ly[k]-w[j][k]<mi)
52          mi=lx[j]+ly[k]-w[j][k];
53          
54          if(mi==0) {cout<<"NO ANSWER!"<<endl;return 0;}
55          for(int j=1;j<=n;++j)
56          {
57            if(vx[j]) lx[j]-=mi;
58            if(vy[j]) ly[j]+=mi;
59                  }
60                }
61              }
62      
63      int sum=0;
64      for(int i=1;i<=n;++i)
65      if(f[i]>0)
66      sum+=w[f[i]][i];
67      
68      if(!p) return -sum;
69      return sum;  
70      } 
71 
72 int main()
73 {
74     cin>>n;
75     for(int i=1;i<=n;++i)
76     for(int j=1;j<=n;++j)
77     cin>>w[i][j];
78     
79     cout<<KM(1)<<endl;   //最大 
80     cout<<KM(0)<<endl;   //最小
81     system("pause");
82     return 0; 
83     
84     } 
posted on 2012-10-22 22:56  怡红公子  阅读(188)  评论(0编辑  收藏  举报