Tour—–最佳二分匹配

來源:互聯網
上載者:User

題目:http://acm.hdu.edu.cn/showproblem.php?pid=3488

註:最小權二分匹配

原始碼:

#include <stdio.h>#include <string.h>#include <algorithm>#define N 305#define INF 1e9     //不要太大using namespace  std;int n,m,cas,u,v,w;int g[N][N],nx,ny; //需要初始化int mx[N],my[N],lx[N],ly[N]; //lx[],ly[]為KM演算法中Xi與Yi的頂點標號bool sx[N],sy[N]; //標記是否在交錯樹上int prev[N],slack[N]; //prev[i]為Y中i點在交錯樹上的前點;slack為鬆弛量int q[N*2],head,tail;void augment(int v){ //增廣    while(v!=-1){        int pv=mx[prev[v]];        mx[prev[v]]=v; my[v]=prev[v];v=pv;    }}bool bfs(){    while(head!=tail){    int p=q[head++],u=p>>1;    if(p & 1){    if(my[u]==-1){ augment(u);return true; }    else { q[tail++]=my[u]<<1; sx[my[u]]=true; }    }    else for(int i=0;i<ny;i++)    if(sy[i])continue;    else if(lx[u]+ly[i]!=g[u][i]){    int ex=lx[u]+ly[i]-g[u][i];    if(slack[i]>ex){ slack[i]=ex; prev[i]=u; }    }    else { prev[i]=u; sy[i]=true; q[tail++]=i*2+1; }    }    return false;}int KMmatch(bool maxsum ){ //預設為最大權匹配    int i,j,ex,cost=0;    if(!maxsum) for(i=0;i<nx;i++) for(j=0;j<ny;j++) g[i][j]*=-1;    memset(mx,-1,sizeof(mx));    memset(my,-1,sizeof(my));    memset(ly,0,sizeof(ly));    for(i=0;i<nx;i++)    for(lx[i]=-INF,j=0;j<ny;j++)    lx[i]=max(lx[i],g[i][j]);    for(int live=0;live<nx;live++){    memset(sx,0,sizeof(sx)); memset(sy,0,sizeof(sy));    for(i=0;i<ny;i++)slack[i]=INF;    head=tail=0; q[tail++]=live*2; sx[live]=true;    while(!bfs()){        for(ex=INF,i=0;i<ny;i++)if(!sy[i]) ex=min(ex,slack[i]);        for(i=0;i<nx;i++) if(sx[i])lx[i]-=ex;        for(j=0;j<ny;j++){ if(sy[j])ly[j]+=ex;slack[j]-=ex;}        for(i=0;i<ny;i++)        if(!sy[i] && slack[i]==0){q[tail++]=i*2+1;sy[i]=true;}        }    }    if(!maxsum) for(i=0;i<nx;i++) for(j=0;j<ny;j++) g[i][j]*=-1;    for(i=0;i<nx;i++)cost+=g[i][mx[i]];    return cost;}int main(){    //freopen("F:\\a.txt","r",stdin);    scanf("%d",&cas);    while(cas--)    {        scanf("%d %d",&n,&m);        for(int i=0;i<n;i++)          for(int j=0;j<n;j++)           g[i][j]=-INF;        for(int i=0;i<m;i++)        {            scanf("%d %d %d",&u,&v,&w);            if(g[u-1][v-1]<-w)             g[u-1][v-1]=-w;        }        nx=ny=n;        printf("%d\n",-KMmatch(true));    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.