HDU 3395 Special Fish

来源:互联网 发布:自动记谱软件 编辑:程序博客网 时间:2024/05/05 20:19

7月冒泡第4题。

大意明白后很好写,注意初始化W的值。

#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <map>using namespace std;const int maxn = 110;const int INF = 0x3f3f3f3f;int n, m;int W[maxn][maxn];int Lx[maxn], Ly[maxn];int Left[maxn];bool S[maxn], T[maxn];bool match(int i){    S[i] = 1;    for(int j = 1; j <= n; j++) if(Lx[i]+Ly[j] == W[i][j] && !T[j])    {        T[j] = 1;        if(!Left[j] || match(Left[j]))        {            Left[j] = i;            return 1;        }    }    return 0;}void update(){    int a = INF;    for(int i = 1; i <= n; i++) if(S[i])    for(int j = 1; j <= n; j++) if(!T[j])        a = min(a, Lx[i]+Ly[j]-W[i][j]);            for(int i = 1; i <= n; i++)    {        if(S[i]) Lx[i] -= a;        if(T[i]) Ly[i] += a;    }}void KM(){    for(int i = 1; i <= n; i++)    {        Left[i] = Lx[i] = Ly[i] = 0;        for(int j = 1; j <= n; j++)            Lx[i] = max(Lx[i], W[i][j]);    }    for(int i = 1; i <= n; i++)    {        for(;;)        {            for(int j = 1; j <= n; j++) S[j] = T[j] = 0;            if(match(i)) break; else update();        }    }}inline void readint(int &x){    char c;    c = getchar();    while(!isdigit(c)) c = getchar();        x = 0;    while(isdigit(c)) x = x*10+c-'0', c = getchar();}inline void writeint(int x){    if(x > 9) writeint(x/10);    putchar(x%10+'0');}int val[maxn];char s[110][110];void read_case(){m = n;for(int i = 1; i <= n; i++) readint(val[i]);for(int i = 1; i <= n; i++) scanf("%s", s[i]+1);}void build(){for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){if(s[i][j] == '1'){W[i][j] = val[i]^val[j];}}}}void solve(){memset(W, 0, sizeof(W));read_case();build();KM();int ans = 0;for(int i = 1; i <= n; i++) if(Left[i]) ans += W[Left[i]][i];writeint(ans), puts("");}int main(){for(readint(n); n; readint(n)){solve();}return 0;}


原创粉丝点击