URAL - 1721 Two Sides of the Same Coin

题意:给出n个人的信息,名字、特征、排名。在排名相差2的前提下,特征为testdata可以与特征为statements的组队,特征为anything可以任何一人组队;

         求最多匹配对数,并将每队名字输出;

思路:构建一个二分图。ok

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define N 1111

int n;
int vis[N];
int link[N];
int mp[N][N];

int abss(int x) {return x>0?x:-x;}


int num1,num2;

struct node {
    char name[30];
    int r;
    char st[20];
    void input() {
        scanf("%s%s%d",name,st,&r);
    }
} p[N];

bool check1(int id) {
    return p[id].st[0] == 's' || p[id].st[0] == 'a';
}

bool check2(int id) {
    return p[id].st[0] =='t' || p[id].st[0] =='a';
}

bool ok(int i, int j)
{
    if(abss(p[i].r-p[j].r)== 2)
    return (check1(i)&&check2(j)) || (check1(j)&&check2(i));
    return false;
}

int dfs(int u) {
    for(int i=1; i<=num2; i++) {
        if(mp[u][i]&&!vis[i]) {
            vis[i] = 1;
            if(link[i]==-1||dfs(link[i])) {
                link[i]=u;
                return 1;
            }
        }
    }
    return 0;
}

int get_match() {
    int ans = 0;
    memset(link,-1,sizeof(link));
    for(int i=1; i<=num1; i++) {
        memset(vis,0,sizeof(vis));
        if(dfs(i))
            ans++;
    }
    return ans;
}



int l[N],r[N];
int main() {
    while(scanf("%d",&n)!=EOF){
     memset(mp,0,sizeof(mp));
     memset(l,0,sizeof(l));
     memset(r,0,sizeof(r));
    int x=0;
    int y=0;
    for(int i=1; i<=n; i++) {
        p[i].input();
        if(p[i].r%4<2) l[++x] = i;
        else r[++y] = i;
    }
    num1= x;
    num2= y;
    /*
    for(int i=1;i<=num1;i++) printf("%d ",l[i]);puts("");
    for(int i=1;i<=num2;i++) printf("%d ",r[i]);puts("");
    */
    //printf("%d %d\n",num1,num2);
    for(int i=1; i<=num1; i++)
        for(int j=1; j<=num2; j++) {
            if(ok(l[i],r[j])) {
                //printf("%d %d\n",l[i],r[j]);
                mp[i][j]=1;
            }
        }
    printf("%d\n",get_match());
    for(int i=1; i<=num2; i++) {
        if(link[i]!=-1) {
            x = r[i];
            y = l[link[i]];
            if(check1(x)&&check2(y)) printf("%s %s\n",p[x].name,p[y].name);
            else printf("%s %s\n",p[y].name,p[x].name);
        }
    }
    }
}


你可能感兴趣的:(URAL - 1721 Two Sides of the Same Coin)