1880: Join the Conversation

Description

Abstract Communication Mastership (ACM) is a software company that develops a unique social networkcalled tWinter.
Each tWinter user has a handle that starts with a commercial at (‘@’) character. Users of tWinter socialnetwork publish short messages to the network.
If a user’s message contains another user’s handle (preceded by a space or at the beginning of the message,and followed by a space or at the end of the message) then it is called a mention.
A sequence of messages is called a conversation if each message in the sequence (except the first one)contains a mention of the author of the previous message in the sequence.
You are hired to find the longest conversation in the given chronological log of messages.

Input

The first line of the input file contains an integer n (1 ≤ n ≤ 50000) — the number of messages in thechronological log.
Each of the next n lines contains a message preceded by its author’s handle, a colon (‘:’) character, anda space.
Each message is at most 139 characters long. Each handle is at most 20 characters long and does notcontain colons or spaces.
The input file contains only characters with ASCII codes between 32 and 126, inclusive, and line breaks.

Output

On the first line of the output file write the length of the longest conversation in the given log. On thesecond line write 1-based indices of the messages in that conversation in ascending order.
If there are multiple longest conversations, write any one of them.

Sample Input

6
@Petr: Leaving for #NEERC tomorrow!
@Roman: This #NEERC is going to be awesome!
@Stone_in_forest: Nothing happened today.
@NEERCNews: @Petr Don’t forget an umbrella :)
@Lydia: @NEERCNews cares about @Petr - so cute ^ ^
@Lydia: @Lydia @NEERCNews @Petr it won’t be raining though!

Sample Output

3
1 4 5
题目大意:
给出一堆消息,让你找出最长的对话,对于对话的定义: 除了第一条的信息之外,剩下的每一条信息都会提及到上一个人,求出最长对话以及序列号
思路:
比赛的时候读错题了,就很尴尬,读清楚题就很容易知道是dp,找出这句话中的最大dp值相加,然后记录路径即可,其中需要注意的是,每一个消息的发送者会出现多次
所以不能每次直接更新,需要处理一下,具体的看代码,最重要的来了(敲黑板)对于这种整个字符串的问题,你永远不知道tm的他的测试数据有几个换行符,有可能是杂交的
所以在这里我们用cin来处理发送人目的就是过滤前一行的的换行符,之后的整个读入
ac代码
#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<iostream>
#include<sstream>
using namespace std;
const int maxn = 500000+5;
int par[maxn];
int dp[maxn];
int n;
int ans=-1;
void print_path(int fa,int start)
{
   if(par[fa]!=0)
    print_path(par[fa],start);
   if(fa!=start)
        printf("%d ",fa);
}
int main()
{
    char foo[500];
    while(~scanf("%d",&n))
    {
        getchar();
        ans=-1;
        map<string,int>Q;
        memset(dp,0,sizeof(dp));
        memset(par,0,sizeof(par));
        string name;
        for(int i=1;i<=n;i++)
        {
            cin>>name;
            name=name.substr(0,name.length()-1);
            gets(foo);
            stringstream ss;
            ss<<foo;
            if(Q[name]==0)
            {
                Q[name]=i;
            }
            dp[i]=1;
           int  first = Q[name];
           //cout<<first<<' '<<i<<endl;
            int tmp_ans=0;
            int tmp_path;
            string s;
            while(ss>>s)
            {
                    if(s[0]=='@')
                    {
                        if(s!=name)
                        {
                            if(Q.find(s)!=Q.end()){
                            if(dp[Q[s]]>tmp_ans)
                            {
                                tmp_ans=dp[Q[s]];
                                tmp_path = Q[s];
                            }
                            }
                        }
                    }
            }
            dp[i]+=tmp_ans;
            if(i!=first)
            {
                if(dp[i]>dp[first]){
                    Q[name]=i;
                }
            }
            if(dp[i]>1)
            par[i]=tmp_path;

        }
        int start;
        for(int i=1;i<=n;i++)
        {
            //cout<<dp[i]<<' '<<i<<endl;
            if(dp[i]>ans)
            {
                ans= dp[i];
                start = i;
            }
        }
        printf("%d\n",ans);
        print_path(start,start);
        printf("%d\n",start);
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值