SGU210——Beloved Sons

来源:互联网 发布:孕38周b超标准数据 编辑:程序博客网 时间:2024/05/02 01:04

1、题意:最大权值和匹配
2、分析:直接上KM即可

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define M 410#define inf 214748364inline int read(){    char ch = getchar(); int x = 0, f = 1;    while(ch < '0' || ch > '9'){        if(ch == '-') f = -1;        ch = getchar();    }    while('0' <= ch && ch <= '9'){        x = x * 10 + ch - '0';        ch = getchar();    }    return x * f;}namespace KM{    #define N 410    int n;    int A[N], B[N];    int w[N][N];    int link[N], ans[N];    bool vis[N], vis1[N];    int mn;     inline void init(){        memset(w, 0, sizeof(w));    }    inline bool find(int x){        vis[x] = true;        for(int i = 1; i <= n; i ++){            if(vis1[i]) continue;            //if(!w[x][i]) continue;            int t = A[x] + B[i] - w[x][i];            if(!t){                vis1[i] = true;                 if(!~link[i] || find(link[i])){                    link[i] = x;                    ans[x] = i;                    return true;                }            }            else mn = min(mn, t);        }        return false;    }    inline void km(){        memset(link, -1, sizeof(link));        memset(A, 0, sizeof(A));        memset(B, 0, sizeof(B));        for(int i = 1; i <= n; i ++){            for(int j = 1; j <= n; j ++){                A[i] = max(A[i], w[i][j]);            }        }        for(int i = 1; i <= n; i ++){            while(1){                memset(vis, 0, sizeof(vis));                memset(vis1, 0, sizeof(vis1));                mn = inf;                if(find(i)) break;                for(int j = 1; j <= n; j ++){                    if(vis[j]) A[j] -= mn;                    if(vis1[j]) B[j] += mn;                 }            }        }    }    inline int getsum(){        int ret = 0;        for(int i = 1; i <= n; i ++) ret += A[i], ret += B[i];        return ret;    }} int a[M];int main(){    int n = read();    for(int i = 1; i <= n; i ++){        a[i] = read(); a[i] *= a[i];    }    KM::n = n;    for(int i = 1; i <= n; i ++){        int t = read();        while(t --){            int x = read();            KM::w[i][x] = a[i];         }    }    KM::km();    for(int i = 1; i <= n; i ++){        printf("%d", KM::w[i][KM::ans[i]] ? KM::ans[i] : 0);        printf("%c", i == n ? '\n' : ' ');    }    return 0;}
0 0