/**
* @file main.cpp
* @brief 求单源最短路径
* 大致题意:Erdos, P.多产的数学家,论文很多
* 现在需要计算任意一人到他的距离,这个距离定义为
* 如果和他合作过论文,距离为1
* 如果没有和他合作过论文,但和与他合作过论文的人合作过,距离为2
* 依次类推
*
* 1.需要把名字映射到编号,std::map亲测可行500ms
* 2.互相合作过的人需要正反各添加一条权为1的边
* 3.spfa可以水过,其它算法不知
* 4.注意一个WA的点是,查距离的用户可能之前的数据中没出现过
*
* @author yekeren
* @version 1.0.0
* @date 2013-06-08
*/
#include <stdio.h>
#include <string.h>
#include <string>
#include <queue>
#include <map>
#define MAX_INT 0x7fffffff
///<名字词典
std::map<std::string, int> dict;
int counter = 0;
///<临接表
struct edge_t {
int b, c;
struct edge_t *next;
} *k[11000] = { NULL }, pool[184000];
int npool = 0;
///<最短路径
int dist[11000] = { 0 };
/**
* @brief 通过名字查找对应的编号
* @param name
* @return
*/
int name_insert(const char *name)
{
std::map<std::string, int>::iterator iter;
if ((iter = dict.find(name)) != dict.end()) {
return iter->second;
} else {
int retval = counter;
dict.insert(std::pair<std::string, int>(name, counter++));
return retval;
}
}
/**
* @brief 临接表添加边
* @param a
* @param b
* @param c
*/
void add_edge(int a, int b, int c)
{
pool[npool].b = b;
pool[npool].c = c;
pool[npool].next = k[a];
k[a] = &pool[npool++];
}
/**
* @brief shortest path faster algorithm
* @param s
*/
void spfa(int s)
{
for (int i = 0; i < sizeof(dist) / sizeof(dist[0]); ++i) {
dist[i] = MAX_INT;
}
dist[s] = 0;
std::queue<int> q;
unsigned char visit[11000] = { 0 };
visit[s] = 1;
q.push(s);
while (!q.empty())
{
int u = q.front();
q.pop();
visit[u] = 0;
for (edge_t *p = k[u]; p != NULL; p = p->next)
{
int v = p->b;
int c = p->c;
if (dist[u] + c < dist[v])
{
dist[v] = dist[u] + c;
if (!visit[v])
{
visit[v] = 1;
q.push(v);
}
}
}
}
}
int main(int argc, char *argv[])
{
int p, n, s, e;
int db = 0;
while (scanf("%d%d", &p, &n), p != 0 && n != 0)
{
getchar();
while (p--)
{
char line[251] = { 0 };
gets(line);
char *pos = strstr(line, ":");
char *ptr = line;
std::vector<int> idlist;
while (ptr && ptr < pos)
{
char *next = NULL;
char *lastname = ptr;
next = strstr(lastname, ",");
*next = '\0';
char *firstname = next + 2;
next = strstr(firstname, ",");
if (!next) next = strstr(firstname, ":");
*next = '\0';
char name[251] = { 0 };
strcpy(name, lastname);
strcat(name, ", ");
strcat(name, firstname);
int index = name_insert(name);
idlist.push_back(index);
if (strcmp(name, "Erdos, P.") == 0) {
s = index;
}
ptr = next + 2;
}
for (int i = 0; i < idlist.size(); ++i)
{
for (int j = i + 1; j < idlist.size(); ++j)
{
add_edge(idlist[i], idlist[j], 1);
add_edge(idlist[j], idlist[i], 1);
}
}
}
spfa(s);
printf("Database #%d\n", ++db);
while (n--)
{
char line[251] = { 0 };
gets(line);
int slen = strlen(line);
if (line[slen - 1] == '\n') {
line[slen - 1] = '\0';
}
e = name_insert(line);
if (dist[e] == MAX_INT) {
printf("%s: infinity\n", line);
}
else {
printf("%s: %d\n", line, dist[e]);
}
}
printf("\n");
}
return 0;
}
POJ 1391 Erdos Numbers 最短路径
最新推荐文章于 2020-08-26 10:42:22 发布