二分匹配 大白例题虽有代码

所有代码:

UVALIVE 4043 Ants

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 210;
const int MAXM = MAXN * MAXN * 2;
const double INF = 1e18;
const double eps = 1e-10;
int nx,ny;
double g[MAXN][MAXN];
int linker[MAXN];
double lx[MAXN],ly[MAXN];
double slack[MAXN];
bool visx[MAXN],visy[MAXN];

bool dfs(int x)
{
    visx[x] = true;
    for (int y = 0 ; y < ny ; y++)
    {
        if (visy[y]) continue;
        double tmp = lx[x] + ly[y] - g[x][y];
        if (fabs(tmp - 0.0) < eps)
        {
            visy[y] = true;
            if (linker[y] == -1 || dfs(linker[y]))
            {
                linker[y] = x;
                return true;
            }
        }
        else if (slack[y] - tmp > eps)
            slack[y] = tmp;
    }
    return false;
}

double KM()
{
    memset(linker,-1,sizeof(linker));
    for (int i = 0 ;  i < MAXN ; i++) ly[i] = 0.0;
    for (int i = 0 ; i < nx ; i++)
    {
        lx[i] = -INF;
        for (int j = 0 ; j < ny ; j++)
            if (g[i][j] - lx[i] > eps)
                lx[i] = g[i][j];
    }
    for (int x = 0 ; x < nx ; x++)
    {
        for (int i = 0 ; i < ny ; i++) slack[i] = INF;
        while (true)
        {
            memset(visx,false,sizeof(visx));
            memset(visy,false,sizeof(visy));
            if (dfs(x)) break;
            double d = INF;
            for (int i = 0 ; i < ny ; i++)
            {
                if (!visy[i] && d - slack[i] > eps)
                    d = slack[i];
            }
            for (int i = 0 ; i < nx ; i++)
            {
                if (visx[i])
                    lx[i] -= d;
            }
            for (int i = 0 ; i < ny ; i++)
            {
                if (visy[i]) ly[i] += d;
                else slack[i] -= d;
            }
        }
    }
    double ret = 0;
    for (int i = 0 ; i < ny ; i++)
        if (linker[i] != -1) ret += g[linker[i]][i];
    return ret;
}

struct point
{
    double x,y;
}white[MAXN],black[MAXN];
int N;

int main()
{
    bool first = true;
    while (scanf("%d",&N) != EOF)
    {
        if (first) first = false;
        else putchar('\n');
        for (int i = 0 ; i < N ; i++)
            scanf("%lf%lf",&white[i].x,&white[i].y);
        for (int i = 0 ; i < N ; i++)
            scanf("%lf%lf",&black[i].x,&black[i].y);
        nx = ny = N;
        for (int i = 0 ; i < N ; i++)
        {
            for (int j = 0 ; j < N ; j++)
            {
                double dis = sqrt((white[i].x - black[j].x) * (white[i].x - black[j].x)
                        + (white[i].y - black[j].y) * (white[i].y - black[j].y));
                g[j][i] = -1.0 * dis;
            }
        }
        KM();
        for (int i = 0 ; i < N ; i++)
            printf("%d\n",linker[i] + 1);
    }
    return 0;
}
View Code

UVA 11383 Golden Tiger Claw

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 510;
const int INF = 0x3f3f3f3f;
int nx,ny;
int N;
int g[MAXN][MAXN];
int w[MAXN][MAXN];
int linker[MAXN],lx[MAXN],ly[MAXN];
int slack[MAXN];
bool visx[MAXN],visy[MAXN];

bool dfs(int x)
{
    visx[x] = true;
    for (int y = 0 ; y < ny ; y++)
    {
        if (visy[y]) continue;
        int tmp = lx[x] + ly[y] - g[x][y];
        if (tmp == 0)
        {
            visy[y] = true;
            if (linker[y] == -1 || dfs(linker[y]))
            {
                linker[y] = x;
                return true;
            }
        }
        else if (slack[y] > tmp)
            slack[y] = tmp;
    }
    return false;
}

int KM()
{
    memset(linker,-1,sizeof(linker));
    memset(ly,0,sizeof(ly));
    for (int i = 0 ; i < nx ; i++)
    {
        lx[i] = -INF;
        for (int j = 0 ; j < ny ; j++)
        {
            if (g[i][j] > lx[i])
                lx[i] = g[i][j];
        }
    }
    for (int x = 0 ; x < nx ; x++)
    {
        for (int i = 0 ; i < ny ; i++) slack[i] = INF;
        while (true)
        {
            memset(visx,false,sizeof(visx));
            memset(visy,false,sizeof(visy));
            if (dfs(x)) break;
            int d = INF;
            for (int i = 0 ; i < ny ; i++)
            {
                if (!visy[i] && d > slack[i])
                    d = slack[i];
            }
            for (int i = 0 ; i < nx;  i++)
            {
                if (visx[i])
                    lx[i] -= d;
            }
            for (int i = 0 ; i < ny ; i++)
            {
                if (visy[i]) ly[i] += d;
                else slack[i] -= d;
            }
        }
    }
    int ret = 0;
    for (int i = 0 ; i < ny ; i++)
        if (linker[i] != -1) ret += g[linker[i]][i];
    return ret;
}

int main()
{
    while (scanf("%d",&N) != EOF)
    {
        for (int i = 0;  i < N ; i++)
            for (int j = 0 ; j < N ; j++)
             scanf("%d",&g[i][j]);
        nx = N;
        ny = N;
        KM();
        for (int i = 0 ; i < N ; i++)
            printf("%d%c",lx[i],i == N - 1 ? '\n' : ' ');
        for (int i = 0 ; i < N ; i++)
            printf("%d%c",ly[i],i == N - 1 ? '\n' : ' ');
        int ret = 0;
        for (int i = 0 ; i < N ; i++)
            ret += lx[i] + ly[i];
        printf("%d\n",ret);
    }
    return 0;
}
View Code

UVALIVE 2238 Fixed Partition Memory Management

Final题就是不一样!

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL int
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 600;
const int MAXD = 600;
const int INF = 0x3f3f3f3f;
int nx,ny;
int g[MAXN][MAXN];
int w[MAXN][MAXN];
int linker[MAXN],lx[MAXN],ly[MAXN];
int slack[MAXN];
bool visx[MAXN],visy[MAXN];

bool dfs(int x)
{
    visx[x] = true;
    for (int y = 0 ; y < ny ; y++)
    {
        if (visy[y]) continue;
        int tmp = lx[x] + ly[y] - g[x][y];
        if (tmp == 0)
        {
            visy[y] = true;
            if (linker[y] == -1 || dfs(linker[y]))
            {
                linker[y] = x;
                return true;
            }
        }
        else if (slack[y] > tmp)
            slack[y] = tmp;
    }
    return false;
}

int KM()
{
    memset(linker,-1,sizeof(linker));
    memset(ly,0,sizeof(ly));
    for (int i = 0 ; i < nx ; i++)
    {
        lx[i] = -INF;
        for (int j = 0 ; j < ny ; j++)
        {
            if (g[i][j] > lx[i])
                lx[i] = g[i][j];
        }
    }
    for (int x = 0 ; x < nx ; x++)
    {
        for (int i = 0 ; i < ny ; i++) slack[i] = INF;
        while (true)
        {
            memset(visx,false,sizeof(visx));
            memset(visy,false,sizeof(visy));
            if (dfs(x)) break;
            int d = INF;
            for (int i = 0 ; i < ny ; i++)
            {
                if (!visy[i] && d > slack[i])
                    d = slack[i];
            }
            for (int i = 0 ; i < nx;  i++)
            {
                if (visx[i])
                    lx[i] -= d;
            }
            for (int i = 0 ; i < ny ; i++)
            {
                if (visy[i]) ly[i] += d;
                else slack[i] -= d;
            }
        }
    }
    int ret = 0;
    for (int i = 0 ; i < ny ; i++)
        if (linker[i] != -1) ret += g[linker[i]][i];
    return ret;
}

int N,M;
int support[MAXD];
pair<int,int>id[MAXD];
int dis[MAXD][MAXD];
struct node
{
    int cnt;
    int S[20],T[20];
}src[MAXD];

void read()
{
    for (int i = 0 ; i < M ; i++) scanf("%d",&support[i]);
    for (int i = 0 ; i < N ; i++)
    {
        scanf("%d",&src[i].cnt);
        for (int j = 0 ; j < src[i].cnt ; j++)
            scanf("%d%d",&src[i].S[j],&src[i].T[j]);
    }
}

void build()
{
    for (int i = 0 ; i < N ; i++)
    {
        for (int j = 0 ; j < M ; j++)
        {
            int tmp;
            if (support[j] < src[i].S[0]) tmp = INF;
            else
            {
                int pos;
                for (pos = 0 ; pos < src[i].cnt ; pos++)
                {
                    if (src[i].S[pos] > support[j]) break;
                }
                pos--;
                tmp = src[i].T[pos];
            }
            dis[i][j] = tmp;
            for (int k = 0 ; k < N ; k++)
            {
                if (tmp == INF) g[i][j  * N + k] = -INF;
                else g[i][j * N + k] = -1LL * (k + 1) * tmp;
                id[j * N + k] = make_pair(j,k);
            }
        }
    }
}

set<pair<int,int> >s[20];
pair<int,int>ret[60];
set<pair<int,int> >::iterator it,temp;
void output(int kase)
{
    printf("Case %d\n",kase);
    for (int i = 0 ; i < 20 ; i++) s[i].clear();
    for (int i = 0 ; i < N * M ; i++)
    {
        if (linker[i] == -1) continue;
        else
        {
            int memory = id[i].first,idx = id[i].second;
            s[memory].insert(make_pair(idx,linker[i]));
        }
    }
    for (int i = 0 ; i < M ; i++)
    {
        if (s[i].empty()) continue;
        int sum = 0;
        it = s[i].end();
        it--;
        for (;;it--)
        {
            int pos = (*it).second;
            int order = (*it).first;
            ret[pos] = make_pair(i,sum);
            sum += dis[pos][i];
            if (it == s[i].begin()) break;
        }
    }
    double sum = 0.0;
    for(int i = 0 ; i < N ; i++) sum += lx[i];
    for (int i = 0 ; i < N * M ; i++) sum += ly[i];
    printf("Average turnaround time = %.2lf\n",fabs(sum / N));
    for (int i = 0 ; i < N ; i++)
    {
        printf("Program %d runs in region %d from %d to %d\n",i + 1,ret[i].first + 1,
                            ret[i].second,ret[i].second + dis[i][ret[i].first]);
    }
    putchar('\n');
}

int main()
{
    int kase = 1;
    while (scanf("%d%d",&M,&N) != EOF)
    {
        if (M == 0 && N == 0) break;
        read();
        build();
        nx = N;
        ny = N * M;
        KM();
        output(kase);
        kase++;
    }
    return 0;
}
View Code

UVALIVE 3989 Ladies' Choice

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1010;
int pref[MAXN][MAXN],order[MAXN][MAXN],next[MAXN];
int future_husband[MAXN],future_wife[MAXN];
queue<int>q;

void engage(int man,int woman)
{
    int m = future_husband[woman];
    if (m)
    {
        future_wife[m] = 0;
        q.push(m);
    }
    future_husband[woman] = man;
    future_wife[man] = woman;
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        int N;
        scanf("%d",&N);
        for (int i = 1 ; i <= N ; i++)
        {
            for (int j = 1 ; j <= N ; j++)
                scanf("%d",&pref[i][j]);
            next[i] = 1;
            future_wife[i] = 0;
            q.push(i);
        }
        for (int i = 1 ; i <= N ; i++)
        {
            for (int j = 1 ; j <= N ; j++)
            {
                int x;
                scanf("%d",&x);
                order[i][x] = j;
            }
            future_husband[i] = 0;
        }
        while (!q.empty())
        {
            int man = q.front(); q.pop();
            int woman = pref[man][next[man]++];
            if (!future_husband[woman]) engage(man,woman);
            else if (order[woman][man] < order[woman][future_husband[woman]])
                engage(man,woman);
            else q.push(man);
        }
        while (!q.empty()) q.pop();
        for (int i = 1;  i <= N ; i++) printf("%d\n",future_wife[i]);
        if (T) putchar('\n');
    }
    return 0;
}
View Code

UVA 11419 SAM I AM

感觉还是不理解啥是匈牙利树。。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1010;
const int MAXM = MAXN * MAXN * 2;
const int INF = 0x3f3f3f3f;
struct Edge
{
    int u,v,w;
    int next;
}edge[MAXM];
int head[MAXN],tot;

void init()
{
    memset(head,-1,sizeof(head));
    tot = 0;
}

void add_edge(int u,int v,int w)
{
    edge[tot].u = u;
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int linker[MAXN],rlinker[MAXN];
bool used[MAXN];
int UN;

bool dfs(int u)
{
    for (int i = head[u]; i != -1 ; i = edge[i].next)
    {
        int v = edge[i].v;
        if (!used[v])
        {
            used[v] = true;
            if(linker[v] == -1 || dfs(linker[v]))
            {
                linker[v] = u;
                rlinker[u] = v;
                return true;
            }
        }
    }
    return false;
}

bool visu[MAXN],visv[MAXN];
bool inu[MAXN],inv[MAXN];

bool calcu(int u)
{
    visu[u] = true;
    for (int i = head[u] ; i != -1 ; i = edge[i].next)
    {
        int v = edge[i].v;
        if (!visv[v])
        {
            visv[v] = true;
            if (linker[v] == -1 || calcu(linker[v]))
            return true;
        }
    }
    return false;
}
int NX,NY,M;
int main()
{
    while (scanf("%d%d%d",&NX,&NY,&M) != EOF)
    {
        if (NX == 0 && NY == 0 && M == 0) break;
        init();
        memset(visu,false,sizeof(visu));
        memset(visv,false,sizeof(visv));
        memset(inu,false,sizeof(inu));
        memset(inv,false,sizeof(inv));
        memset(linker,-1,sizeof(linker));
        memset(rlinker,-1,sizeof(rlinker));
        for (int i = 0 ; i < M ; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            x--;
            y--;
            add_edge(x,y,9797);
            inu[x] = true;
            inv[y] = true;
        }
        int ret = 0;
        for (int i = 0 ; i < NX ; i++)
        {
            memset(used,false,sizeof(used));
            if (dfs(i)) ret++;
        }
        printf("%d",ret);
        for (int i = 0 ; i < NX ; i++) if (rlinker[i] == -1) calcu(i);
        for (int i = 0 ; i < NX ; i++) if (inu[i] && !visu[i]) printf(" r%d",i + 1);
        for (int i = 0 ; i < NY ; i++) if (inv[i] && visv[i]) printf(" c%d",i + 1);
        putchar('\n');
    }
    return 0;
}
View Code

UVALIVE 3415 Guardian of Decency

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 510;
const int MAXM = MAXN * MAXN * 2;
const int INF = 0x3f3f3f3f;
struct Edge
{
    int u,v,next;
    int w;
}edge[MAXM];
int head[MAXN],tot;

void init()
{
    tot = 0;
    memset(head,-1,sizeof(head));
}

void add_edge(int u,int v,int w)
{
    edge[tot].u = u ;
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

bool used[MAXN];
int linker[MAXN];
int NX,NY,N;
bool dfs(int u)
{
    for (int i = head[u] ; i != -1 ; i = edge[i].next)
    {
        int v = edge[i].v;
        if (!used[v])
        {
            used[v] = true;
            if(linker[v] == -1 || dfs(linker[v]))
            {
                linker[v] = u;
                return true;
            }
        }
    }
    return false;
}

struct node
{
    int height;
    int music;
    int sport;
}man[MAXN],woman[MAXN];
map<string,int>act,art;
char str[MAXN],res[MAXN];

void build()
{
    init();
    for (int i = 0 ; i < NX; i++)
    {
        for (int j = 0 ; j < NY ; j++)
        {
            if (abs(man[i].height - woman[j].height) <= 40 &&
                    man[i].music == woman[j].music &&
                        man[i].sport != woman[j].sport)
            add_edge(i,j,9797);
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        act.clear();
        art.clear();
        scanf("%d",&N);
        NX = NY = 0;
        int cas = 1,leap = 1;
        for (int i = 0 ; i < N ; i++)
        {
            int height;
            char tmp[5];
            scanf("%d%s%s",&height,tmp,str);
            if (!art[str]) art[str] = cas++;
            scanf("%s",res);
            if (!act[res]) act[res] = leap++;
            if (tmp[0] == 'F')
            {
                man[NX].height = height;
                man[NX].music = art[str];
                man[NX++].sport = act[res];
            }
            else
            {
                woman[NY].height = height;
                woman[NY].music = art[str];
                woman[NY++].sport = act[res];
            }
        }
        build();
        int ret = 0;
        memset(used,false,sizeof(used));
        memset(linker,-1,sizeof(linker));
        for (int i = 0 ; i < NX ; i++)
        {
            memset(used,false,sizeof(used));
            if (dfs(i)) ret++;
        }
        printf("%d\n",N - ret);
    }
    return 0;
}
View Code

UVALIVE 3126 Taxi Cab Scheme

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 510;
const int MAXM = MAXN * MAXN * 2;
const int INF = 0x3f3f3f3f;
struct Edge
{
    int u,v,next;
    int w;
}edge[MAXM];
int head[MAXN],tot;

void init()
{
    tot = 0 ;
    memset(head,-1,sizeof(head));
}

void add_edge(int u,int v,int w)
{
    edge[tot].u = u;
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int NX,NY,N;
int linker[MAXN];
bool used[MAXN];
bool dfs(int u)
{
    for (int i = head[u]; i != -1 ; i = edge[i].next)
    {
        int v = edge[i].v;
        if (!used[v])
        {
            used[v] = true;
            if (linker[v] == -1 || dfs(linker[v]))
            {
                linker[v] = u;
                return true;
            }
        }
    }
    return false;
}

struct node
{
    int stx,sty;
    int edx,edy;
    int tim;
}src[MAXN];

void read()
{
    scanf("%d",&N);
    for (int i = 0 ; i < N ; i++)
    {
        int tmp1,tmp2;
        scanf("%d:%d%d%d%d%d",&tmp1,&tmp2,&src[i].stx,&src[i].sty,&src[i].edx,&src[i].edy);
        src[i].tim = tmp1 * 60 + tmp2;
    }
    init();
    for (int i = 0 ; i < N ; i++)
    {
        for (int j = 0 ; j < N ; j++)
        {
            if (i == j) continue;
            int dis = abs(src[i].edx - src[j].stx) + abs(src[i].edy - src[j].sty);
            if (src[i].tim + abs(src[i].edx - src[i].stx) + abs(src[i].edy - src[i].sty) + dis
                 + 1 <= src[j].tim)
                    add_edge(i,j,9797);
        }
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        read();
        memset(linker,-1,sizeof(linker));
        NX = NY = N;
        int ret = 0;
        for (int i = 0 ; i < NX ; i++)
        {
            memset(used,false,sizeof(used));
            if (dfs(i)) ret++;
        }
        printf("%d\n",N - ret);
    }
    return 0;
}
View Code

 

posted @ 2015-09-12 13:28  Commence  阅读(191)  评论(0编辑  收藏  举报