poj 1403 What's In A Name? 唯一匹配

 

题目

  给N个name ,与N个id, 及其之间关系, 求唯一匹配

解法

  删除边(u,v)后若匹配数减小,则证明此边必定为唯一匹配。 时间复杂度有点高。

View Code
#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<algorithm>

#include<string>

#include<map>

#include<iostream>

using namespace std;

 

map<string,int> mp_name,mp_id;



char id_name[30][30], na_name[30][30] ;



struct node{

    char Name[30], ID[30];

    bool operator < ( node tmp )const{

        return (strcmp(Name,tmp.Name)<=0);    

    }

}res[30];



int n, cnt;

int ma[30], mb[30], match[30];

bool g[30][30], vis[30];

char tmp_str[120];



void input(){

    mp_name.clear(); mp_id.clear(); 

    for(int i = 0; i < n; i++){

        scanf("%s", id_name[i] );

        mp_id[ id_name[i] ] = i;    

    }



    char op[2], str[30]; 

    memset( vis, 0, sizeof(vis)); 

    for(int i = 0; i < n; i++){

        for(int j = 0; j < n; j++)

            g[i][j] = 1;    

    }

    cnt = 0; // record the number of peason

    while( scanf("%s",op) != EOF ){

        if( op[0] == 'Q' ) break; 

        

        if( op[0] == 'E' || op[0] == 'L' ){

            scanf("%s", str); // str is the user name.

            if( mp_name.count(str) == 0 ){ // add new user name 

                strcpy( na_name[cnt], str );  

                mp_name[str] = cnt++;

            }

            if( op[0] == 'E' )     vis[ mp_name[str] ] = 1;         

            else    vis[ mp_name[str] ] = 0; 

        }

        else { // op[0] == 'M'

            scanf("%s", str); // str is the id of user~

            for(int i = 0; i < n; i++) // the peason name's index.

            { 

            //    if( vis[i] ) g[ mp_id[str] ][ i ] = 1;

            //    else    g[ mp_id[str] ][ i ] = 0; 

                if( !vis[i] ) g[i][mp_id[str]] = 0; // user's name ---> user's ID

            }

        }    

    }  

    //for(int i = 0; i < n; i++){

    //    for(int j = 0; j < n; j++)

    //        printf("%d ", g[i][j] );

    //    puts("");    

//    }

}

int path( int u ){ 

    for(int v = 0; v < n; v++){ 

        if( g[u][v] && !vis[v] ){

            vis[v] = 1;

            if( ma[v] == -1 || path( ma[v] ) ){

                ma[v] = u; mb[u] = v;

                return 1;    

            }    

        }     

    }    

    return 0;

}

void solve(){

    memset( match, 0xff, sizeof(match));

    int cnt1 = 0, cnt2;

    for(int x = 0; x < n; x++) // user's name

    for(int y = 0; y < n; y++){ // user's ID

        if( g[x][y] == 0 ) continue;

        cnt1 = 0; cnt2 = 0;

        memset( ma, 0xff, sizeof(ma));

        memset( mb, 0xff, sizeof(mb));

        for(int i = 0; i < n; i++){

            if( mb[i] == -1 ){

                memset( vis, 0, sizeof(vis));

                cnt1 += path( i );    

            }    

        }    

        memset( ma, 0xff, sizeof(ma));

        memset( mb, 0xff, sizeof(mb));

        g[x][y] = 0;

        for(int i = 0; i < n; i++){

            if( mb[i] == -1 ){

                memset( vis, 0, sizeof(vis));

                cnt2 += path( i );    

            }    

        }

        g[x][y] = 1;

        if( cnt1 > cnt2 ){

            match[x] = y; // user's name => user's ID

            break;

        }

        

    }

    // printf("cnt = %d\n", cnt );

    // operator for alphabetical order 

    for(int i = 0; i < n; i++){

        strcpy( res[i].Name, na_name[i] );

        if( match[i] != -1 )    strcpy( res[i].ID, id_name[ match[i] ] );

        else    strcpy( res[i].ID, "???" );

    }

    sort( res, res+n );

    for(int i = 0; i < n; i++)

        printf("%s:%s\n", res[i].Name, res[i].ID );

}

int main(){ 

    while( scanf("%d", &n) != EOF ){

        input(); 

        solve();     

    }

    return 0;    

}

  

  不过听叉姐说有,O(1)的判定。 poj 1904

  http://bbezxcy.iteye.com/blog/1392582

你可能感兴趣的:(name)