ZOJ-1129-Erdos Numbers

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1129

题目大意:

和Erods合作的作者,其Erdos number 是1,没有和Erdos合作的,但是和Erods number是1的作者合作的作者,其Erdos number是2,以此类推。

编程任务:

         对给定的一组科学家,计算每位科学家的Erods number。

算法分析:

         此题难点主要是对字符串的处理,然后用广度优先搜索求解。

         分别对每个作者进行编号,将作者之间的关系构造成邻接矩阵。如果用普通字符串的处理为作者编号,比较麻烦,效率也低,可以利用map()容器。以姓名为key,值为编号

         map<string, int > name;

         读入数据时,对于每一篇论文,作者编号存放于paper[]中,根据作者编号,构建邻接矩阵。最后用广搜进行求解。

#include<iostream>
#include<map>
#include<queue>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;

struct Editor{
    int ID;    //作者编号
    int Num;//Erdos number 号
};

vector<int>data[10000];    //存储邻接矩阵
map<string,int> name;    //作者编号
map<string,int>::iterator pos;
int author[10000];        //各个作者的Erdos number
string Erdos = "Erdos,P.";

void bfs()    //广搜求解
{
    queue<Editor>Q;
    Editor tmp,now;
    int i,id,nNum;
    memset(author,-1,sizeof(author));
    tmp.ID = name[Erdos];
    tmp.Num = 0;
    Q.push(tmp);
    while(!Q.empty())
    {
        now = Q.front();    Q.pop();
        id = now.ID;
        nNum = data[id].size();
        for(i=0;i<nNum;i++)
        {
            if(author[data[id][i]] == -1)
            {
                author[data[id][i]] = now.Num + 1;    //
                tmp.ID = data[id][i];
                tmp.Num = now.Num + 1;
                Q.push(tmp);    //合作者进入队列
            }
        }
    }
}

int main()
{
    char str[300];
    string fullname;
    int p,n,len,numAuthor,numPaper,i,j,title;
    int paper[300],iCase = 0;
    while(scanf("%d%d",&p,&n)!=EOF && p+n)
    {
        for(i=0;i<10000;i++)
            data[i].clear();
        name.clear();
        numAuthor = 0;
        while(p--)
        {
            numPaper = 0;
            int flag = 1;
            while(1)
            {
                scanf("%s",str);
                fullname = str;
                scanf("%s",str);    len = strlen(str);
                if(str[len-1] == ':' || str[len-1] == '.')        flag = 0;
                str[len-1] = '\0';
                fullname += str;
                pos = name.find(fullname);
                if(pos == name.end())    //如果姓名不存在,加进去
                    name[fullname] = numAuthor ++;
                paper[numPaper++] = name[fullname];    //加入paper[]
                if(!flag)
                {
                    gets(str);    break;
                }
            }
            for(i=0;i<numPaper;i++)    //建立论文作者之间的关系
            {
                for(j=0;j<numPaper;j++)
                {
                    if(i!=j)
                        data[paper[i]].push_back(paper[j]);
                }
            }
        }
        pos = name.find(Erdos);
        if(pos == name.end())    name[Erdos] = numAuthor++;
        bfs();
        printf("Database #%d\n",++iCase);
//        for(i=0;i<numAuthor;i++)
//            printf("%d  ",author[i]);
//        printf("\n");
        while(n--)
        {
            scanf("%s",str);    printf("%s",str);
            fullname = str;
            scanf("%s",str);    printf(" %s: ",str);
            fullname +=str;
            pos = name.find(fullname);
            if(pos == name.end() || author[name[fullname]]==-1)
                printf("infinity\n");
            else printf("%d\n",author[name[fullname]]);
        }
        printf("\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/pcoda/archive/2012/09/02/2667992.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值