题目大意
![这里写图片描述](https://img-blog.csdn.net/20170328122012412?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2h1bmtpdGxhdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
解题思路
先跑一遍最大费用流,每次删除一种配对,重新跑一遍,最大费用改变即必选。
code
using namespace std;
int const Mxn=180,Mxm=10000,Inf=1e9;
int N,Cost[Mxn][Mxn],Size[Mxn][Mxn],Q[Mxm],Inq[Mxn],Dis[Mxn],Pre[Mxn],
Next[Mxn];
int Spfa(int S,int T){
int He=0,Ti=0;
Inq[Q[++Ti]=S]=1;
Fo(i,0,N*2+1)Pre[i]=-1,Dis[i]=-Inf;Dis[S]=0;
while(He!=Ti){
int Now=Q[++He];
Fo(i,0,N*2+1)if(Size[Now][i]&&(Dis[i]<Dis[Now]+Cost[Now][i])){
Dis[i]=Dis[Now]+Cost[Now][i];
Pre[i]=Now;
if((!Inq[i])&&(i!=T))Inq[Q[++Ti]=i]=1;
}
Inq[Now]=0;
}
int Tmp=T,Ans=0;
while(Tmp!=S){
Size[Pre[Tmp]][Tmp]--;
Size[Tmp][Pre[Tmp]]++;
Ans+=Cost[Pre[Tmp]][Tmp];
Tmp=Pre[Tmp];
}
return Ans;
}
int main(){
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
scanf("%d",&N);
Fo(i,1,N)Fo(j,N+1,N*2)scanf("%d",&Cost[i][j]),Cost[j][i]=-Cost[i][j],Size[i][j]=1;
Fo(i,1,N)Size[0][i]=Size[N+i][N*2+1]=1;
int MaxCost=0;
Fo(i,1,N)MaxCost+=Spfa(0,N*2+1);
printf("%d\n",MaxCost);
Fo(i,1,N)Fo(j,N+1,N*2)if(!Size[i][j]){Next[i]=j;break;}
Fo(i,1,N){
Fo(j,1,N)Fo(k,N+1,N*2)Size[j][k]=1,Size[k][j]=0;
Size[i][Next[i]]=Size[Next[i]][i]=0;
Fo(j,1,N)Size[0][j]=Size[N+j][N*2+1]=1,Size[j][0]=Size[N*2+1][N+j]=0;
int Tmp=0;
Fo(j,1,N)
Tmp+=Spfa(0,N*2+1);
if(Tmp!=MaxCost)printf("%d %d\n",i,Next[i]-N);
}
return 0;
}