POJ1043 What's In A Name?
题目来源:http://poj.org/problem?id=1043
题目大意:
一个犯罪团伙有n个成员,每人有一个唯一的字符串作为id,每人还有一个唯一的字符串作为name。该团伙有一个hideout系统,成员利用这个系统进行通信。成员进入hideout后可以发出信息,发出的信息会留下发送者的id。现在FBI获得了hideout的log记录,包括成员进入和离开的记录以及系统中发送信息的记录。其中,成员进入和离开记录的是他们的name,发送的信息记录的是id。成员只有在hideout中才能发送信息。整个log中每个成员至少出现一次,但不一定每个人都会发送信息。FBI希望通过这些记录确定犯罪团伙中每个成员的name和id的匹配关系。hideout初始时视为没有人。
输入:由单个测试用例组成。第一行整数n表示人数。第二行n个字符串表示每个人的id。接下来的每行为一条记录。由一个字符和一个字符串组成。‘E’表示进入,‘L’表示离开,后面的字符串是该人的name,‘M’表示发送了一条信息,后面接发送人id。‘Q’表示结束。
输出:输出由n行组成,每行输出name:id的匹配对,若某个name无法确定其id输出name:???。按name字典序输出。
Sample Input
7
bigman mangler sinbad fatman bigcheese frenchie capodicapo
E mugsy
E knuckles
M bigman
M mangler
L mugsy
E clyde
E bonnie
M bigman
M fatman
M frenchie
L clyde
M fatman
E ugati
M sinbad
E moriarty
E booth
Q
Sample Output
bonnie:fatman
booth:???
clyde:frenchie
knuckles:bigman
moriarty:???
mugsy:mangler
ugati:sinbad
该题与二部图的匹配问题紧密相关。之前的一篇博客已经介绍过了这道题里要用到的与二部图相关的理论基础。
请戳:http://www.cnblogs.com/dengeven/p/3230406.html
但是仅仅意识到与二部图匹配有关还不足以解决问题,因为我们要找的是确定会出现在完全匹配中的边。
首先,图的建立就是有小技巧的。如果按log顺序处理,每发出一条信息,连接在hideout中的name与信息显示的id,当有人离开发现矛盾再删除边这样的策略的话,可能被漏掉的情况很多,因为有人可能没有发出信息,即有的id不会显示在log中。简便的处理方法是初始时把所有连接都设为true,当出现一条信息时,删掉该id与不在hideout中的name的连接。这样就不会漏掉边。
然后,因为id与name是一一对应的,其实也就是说图应该有唯一的完全匹配,匹配数为n。确定每个name对于的id的方法是:遍历与name相接的每条边,如果去掉该条边,剩余图的最大匹配数小于n,说明这条边一定是唯一完全匹配中的,即与该name匹配的id可以确定,否则无法确定。
//////////////////////////////////////////////////////////////////////////
// POJ1043 What's In A Name
// Memory: 252K Time: 16MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <cstring>
#include <iostream>
#include <algorithm> using namespace std; int n; //人数
char id[][]; //记录每个id
char name[][]; //记录每个name
int order[]; //name字典序序号
bool in_hideout[];//in_hideout[i]为true表示第i个人在hideout内
bool graph[][]; //graph[i][j]为true表示第i个name与第j个id有可能匹配
int link_name[]; //link_name[i]:匹配中与id为i的顶点相连的name编号
bool visited[]; //顶点访问标记数组
int match_id[]; //match_id[i]为确定后第i个name匹配的id号,不确定的为-1 inline int cmp(int i,int j){
if (memcmp(name[i],name[j],sizeof name[i]) <= ) return ;
else return ;
} //dfs寻找增广路
int findPath(int k){
for (int i = ; i < n; ++i) {
if (graph[k][i] && visited[i] == false){
visited[i] = true;
if (link_name[i] == - || findPath(link_name[i])){
link_name[i] = k;
return ;
}
}
}
return ;
} //匈牙利算法求最大匹配
int hungary(){
int cnt = ;
memset(link_name,-,sizeof(link_name));
for (int i = ; i < n; ++i) {
memset(visited, , sizeof(visited));
cnt += findPath(i);
}
return cnt; //最大匹配数
} int main(){
cin >> n;
for (int i = ; i < n; ++i) cin >> id[i];
memset(graph, true, sizeof(graph));
memset(match_id, -, sizeof(match_id));
memset(in_hideout, false, sizeof(in_hideout));
int name_cnt = ;
char log_type;
char buf[];
while (true) {
cin >> log_type;
if (log_type == 'Q') break;
cin >> buf;
int i;
switch (log_type){
case 'E':
for (i = ; i < name_cnt && strcmp(buf, name[i]) != ; ++i);
if (i == name_cnt) {
strcpy(name[name_cnt++], buf);
}
in_hideout[i] = ;
break;
case 'L':
for (i = ; i < name_cnt && strcmp(buf, name[i]) != ; ++i);
in_hideout[i] = ;
break;
case 'M':
for (i = ; i < n && strcmp(buf,id[i]) != ; ++i);
for (int j = ; j < n; ++j) {
if (!in_hideout[j]) {
graph[j][i] = false;
}
}
break;
}
}
for (int i = ; i < n; ++i){
for (int j = ;j < n; ++j) {
if (graph[i][j]) {
graph[i][j] = false;
if (hungary() != n) {
//该边是最大匹配的必须边,是确定的匹配
graph[i][j] = true;
match_id[i] = j;
break;
}
graph[i][j] = true;
}
}
}
for (int i = ; i < n; ++i) order[i] = i; //按name字典序输出
sort(order,order + n,cmp);
for (int i = ;i < n;i ++){
cout << name[order[i]] << ":";
if (match_id[order[i]] == -) {
cout << "???" << endl;
} else {
cout << id[match_id[order[i]]] << endl;
}
}
system("pause");
return ;
}
POJ1043 What's In A Name?的更多相关文章
- POJ1043问题描述
Description The FBI is conducting a surveillance of a known criminal hideout which serves as a commu ...
随机推荐
- freeMarker(十四)——XML处理指南之必要的XML处理
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net 1.基本内容 假设程序员在数据模型中放置了一个XML文档,就是名为 d ...
- Linux下几种RTP协议实现的比较和JRTPLIB编程讲解
流媒体指的是在网络中使用流技术传输的连续时基媒体,其特点是在播放前不需要下载整个文件,而是采用边下载边播放的方式,它是视频会议. IP电话等应用场合的技术基础.RTP是进行实时流媒体传输的标准协议和关 ...
- Java 处理批量数据提交
在Java web开发过程中,处理表单数据是很重要一部分,常见的是form post处理单条数据的,但也会遇到一次提交多条数据到服务器的,如下:
- Anthem.NET的 "Bad Response" 问题,及脚本调试技巧小结
今天解决了一位朋友使用 Anthem.NET 遇到的问题.他的代码在 Windows XP 的开发机器上反应正常,而部署到 2003 Server 的服务器上就提示 "BADRESPONSE ...
- saltstack集中化管理平台
1.安装与启动 yum install salt-master -y 安装服务端 chkconfig salt-master on 自启动 service salt-master start 启动 y ...
- Oracle数据库安全性设计
一.什么是安全的系统 安全性建设是一个长期并且卓绝的工作.作为一个符合标准的企业级系统,我们认为税务系统应该具备以下的安全性特点: ◆高可用性 ◆对敏感数据的访问控制能力. ◆监测用户行为的审计能力. ...
- hibernate 持久化对象的生命周期
持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...
- 应用HtmlInputFile进行大文件上传 解决asp.net上传大文件默认文件大小限制
选择一个文件,也可以正确上传至服务器,但您会发现文件大于2048的时候,出现:Internet Explorer显示 "The page cannot be displayed - Cann ...
- Material使用09 MdCheckboxModule、MdMenuModule、MdTooltipModule
1 MdCheckboxModule的使用 md-checkbox 实现的功能和 <input type="checkbox"> 相同,只不过 md-checkbo ...
- Material使用07 MdGridListModule的使用
1 MatGridListModule简介 对相似数据的展现,尤其是像是图片的展示 使用起来很像表格 官方文档:点击前往 2 MatGridListModule提供的指令 2.1 mat-grid-l ...