题意:给出n条发言,每@一次为一次交流,求最长的连续交流长度,并按顺序输出。前面的人不能@后面的人。
分析:对于每一层,更新到这一层的最大长度,并记录下父节点。
细节参见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<sstream>
using namespace std;
const int maxn=50000+10;
int n;
stack<int> s;
string buf,str,name;
struct node
{
int d,p;
node(int u=0,int v=0) :d(u),p(v) {}
};
map<string,node> mp;
int dp[maxn],pre[maxn];
int main()
{
while(scanf("%d",&n)==1)
{
getchar();
mp.clear();
for(int i=1;i<=n;i++)
{
dp[i]=1;
pre[i]=-1;
getline(cin,str);
stringstream ss(str);
ss>>name;
name.resize(name.size()-1);
if(!mp.count(name))
{
node u(1,i);
mp[name]=u;
}
while(ss>>buf)
{
if(!mp.count(buf)||buf==name) continue;
if(mp[buf].d+1>dp[i])
{
dp[i]=mp[buf].d+1;
pre[i]=mp[buf].p;
}
}
if(mp[name].d<dp[i])
{
mp[name]=node(dp[i],i);
}
}
int p=1,ans=0;
for(int i=1;i<=n;i++)
if(dp[i]>ans)
{
p=i;
ans=dp[i];
}
while(p!=-1)
{
s.push(p);
p=pre[p];
}
printf("%d\n",ans);
int is=1;
while(s.size())
{
if(is) {printf("%d",s.top());is=0;}
else printf(" %d",s.top());
s.pop();
}
printf("\n");
}
return 0;
}