poj 1043 What's In A Name 二分匹配
2012-12-02 11:43
435 查看
题意:
有n(1<=n<=20)个人,每一个人在发电报的时候是以固定的绰号发送的,现在给定一串序列表示某个人进入房间,某个人从房间出去,或者截获了以什么绰号发送的电报,问能否推出每个人对应的绰号是什么,如果推理不出来输出"???"。
解题思路:
如果删除某边后最大匹配数变小,这条边便是唯一匹配方案,是所要的答案
View Code
这个是八数码问题??
不清楚吧,当二分图来练习了。
用STL来A题,这是头一次,map,set,感觉功能好犀利。
有n(1<=n<=20)个人,每一个人在发电报的时候是以固定的绰号发送的,现在给定一串序列表示某个人进入房间,某个人从房间出去,或者截获了以什么绰号发送的电报,问能否推出每个人对应的绰号是什么,如果推理不出来输出"???"。
解题思路:
如果删除某边后最大匹配数变小,这条边便是唯一匹配方案,是所要的答案
View Code
#include<cstdio> // poj 1043 What's In A Name? #include<iostream> // 224K 47MS C++ #include<cstring> #include<string> #include<algorithm> #include<map> // 该题字符串的处理很多,用了 map 和 set 来存储数据 #include<set> using namespace std; const int MAXN = 30; int T, cas; int n; string real[MAXN], reco[MAXN]; // 用户名和代号 string sign, name; // 输入所用的变量 map< string, int >mp1; // 用来保存用户名 map< string, int >mp2; // 用来记录代号 bool g[MAXN][MAXN], vis[MAXN]; // 17-18 匈牙利算法所用的变量 int cx[MAXN], cy[MAXN], nx, ny; set< int >cur; // set 的插入与消去,好好用,第一次实用 pair< string, int >pair1[MAXN]; // 20-21 解的保存,pair的第一次实用 int os[MAXN]; /**************** 1-3 函数是算法模板 **********************/ void init() { memset( g, true, sizeof(g) ); } int dfs( int u ) { int v; for( v = 1; v <= ny; v++ ) { if( g[u][v] && !vis[v] ) { vis[v] = true; if( !cy[v] || dfs( cy[v] ) ) { cx[u] = v; cy[v] = u; return 1; } } } return 0; } int MaxMatch() { int u, ret; memset( cx, 0, sizeof(cx) ); memset( cy, 0, sizeof(cy) ); ret = 0; for( u = 1; u <= nx; u++ ) { if( !cx[u] ) { memset( vis, false, sizeof(vis) ); ret += dfs( u ); } } return ret; } /************ 数据的读入 ***************/ void readcase() { int i; scanf( "%d", &n ); for( i = 1; i <= n; i++ ) { cin>>real[i]; mp1[real[i]] = i; } int cnt; cnt = 0; while( cin>>sign, sign != "Q" ) { cin>>name; if( sign == "E" ) { if( mp2[name] == 0 ) { mp2[name] = ++cnt; reco[cnt] = name; } int y = mp2[name]; cur.insert( y ); // set 的插入 } else if( sign == "L" ) { int y = mp2[name]; cur.erase( y ); // set 的消去元素 } else { int x = mp1[name]; for( i = 1; i <= n; i++ )if( cur.find( i ) == cur.end() ) g[x][i] = false; // 去掉没有关系的边 } } nx = ny = n; // 待验证?????????????????????? } void deal( int mat ) // 枚举去掉存在的边,在求最大匹配,如减少,则该边存在 { int i, j, tmp; for( i = 1; i <= n; i++ ) { pair1[i] = make_pair( reco[i], i ); os[i] = 0; for( j = 1; j <= n; j++ ) { if( g[j][i] ) { g[j][i] = false; tmp = MaxMatch(); if( tmp != mat ) { os[i] = j; } g[j][i] = true; } } } sort( pair1 + 1, pair1 + n +1 ); // 对解的排序 } void print() { int i, j; for( i = 1; i <= n; i++ ) { cout<< pair1[i].first << ":"; if( os[pair1[i].second] == 0 ) cout<< "???" << endl; else cout<< real[os[pair1[i].second]] << endl; } } int main() { init(); readcase(); int mat; mat = MaxMatch(); deal( mat ); print(); return 0; }
这个是八数码问题??
不清楚吧,当二分图来练习了。
用STL来A题,这是头一次,map,set,感觉功能好犀利。
相关文章推荐
- zoj 1059 poj 1043 What's In A Name?(二分匹配)
- POJ-1043 What's In A Name? 反面构图+枚举边计算最大匹配
- POJ 1043 What's In A Name?(唯一的最大匹配方法)
- 【二分图|推理+最大匹配】POJ-1043 What's In A Name?
- poj 1403 What's In A Name? 唯一匹配
- POJ1043 What's In A Name?
- POJ 1043 What's In A Name? 二分图推理
- POJ1043.What's In A Name?——反面构图+二分匹配
- POJ 1043 What's In A Name? 已被翻译
- 【HDU】5899 oasis in desert 【二分匹配】
- poj 3020 二分最大匹配
- POJ 3020 Antenna Placement【二分匹配——最小路径覆盖】
- POJ 2536 Gopher II 二分匹配
- POJ 2594 最小路径覆盖 二分匹配
- poj1904 - King's Quest 强连通解决二分匹配问题
- POJ 1469 COURSES(二分匹配-hungary)
- POJ 3189 Steady Cow Assignment(二分+多重匹配)
- 【POJ】1274 The Perfect Stall 二分匹配
- Poj 1548 Robots【最小路径覆盖---二分匹配】
- poj 1486 Sorting Slides 二分匹配唯一性判定