Tour HDU - 3488 二分图最小权值匹配 模板

#pragma GCC optimize (3,"inline","Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x) {
    Finish_read=0;
    x=0;
    int f=1;
    char ch=getchar();
    while(!isdigit(ch)) {
        if(ch=='-')f=-1;
        if(ch==EOF)return;
        ch=getchar();
    }
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    x*=f;
    Finish_read=1;
}
const int N=505;
const int inf=2e9+7;
int n,m;
int wx[N],wy[N],weight[N][N],slack[N];
int belong[N],visx[N],visy[N];
int FindPath(int u) {
    visx[u]=1;
    for(int v=1; v<=n; v++) {
        if(visy[v]) 
            continue;
        int t=wx[u]+wy[v]-weight[u][v];
        if(!t) {
            visy[v]=1;
            if(belong[v]==-1||FindPath(belong[v])) {
                belong[v]=u;
                return 1;
            }
        } else if(slack[v]>t) 
            slack[v]=t;
    }
    return 0;
}

int Km() {
    for(int i=1; i<=n; i++) 
        wx[i]=-inf;
    for(int i=1; i<=n; i++) 
        for(int j=1; j<=n; j++) 
            wx[i]=max(wx[i],weight[i][j]);
    for(int i=1; i<=n; i++) { 
        for(int j=1; j<=n; j++) 
            slack[j]=inf;
        while(1) {
            memset(visx,0,sizeof visx);
            memset(visy,0,sizeof visy);
            if(FindPath(i)) 
                break;
            int ret=inf;
            for(int j=1; j<=n; j++) 
                if(!visy[j]&&ret>slack[j]) 
                    ret=slack[j];
            for(int j=1; j<=n; j++) 
                if(visx[j]) 
                    wx[j]-=ret;
            for(int j=1; j<=n; j++) 
                if(visy[j]) 
                    wy[j]+=ret;
                else 
                    slack[j]-=ret;
            }       
    }
    
    int ans=0;
    for(int i=1; i<=n; i++) 
        if(~belong[i]) 
            ans+=weight[belong[i]][i];
    return ans;
}

int main() {
    int t;
    cin>>t;
    while(t--) {
        scanf("%d%d", &n, &m);
        memset(belong,-1,sizeof belong);
        memset(weight,-inf,sizeof weight);
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            scanf("%d%d%d", &u, &v, &w);
            weight[u][v] = max(weight[u][v], -w);
        }
        
        printf("%d\n",-Km());
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12433267.html