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

原文地址:https://www.cnblogs.com/yefeng1627/p/2999260.html