您的位置:首页 > 其它

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

2013-04-04 12:55 405 查看
题目

  给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

  /article/3814681.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: