思路: 1、先利用top排序求最长路径 2、再利用反向建图,bfs求构成最长路径的所有可能节点 90分,代码如下,求助:
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
struct Edge{
int to,next,w;
} e[maxn*10];
int head[maxn],n,m,pre[maxn],k=0,head2[maxn];
int dp[maxn],rd[maxn];//dp[i]表示看完剧情i需要花费的时间
int b[maxn],cnt=0;
bool vis[maxn];//vis[i]表示i点是否已经在最大路径上
void add(int u,int v,int w){
e[++k].to=v; e[k].w=w;
e[k].next=head[u]; head[u]=k;
e[++k].to=u; e[k].w=w;//反向建图
e[k].next=head2[v]; head2[v]=k;
}
void Top(){//拓扑排序
int u,v;
queue<int> q;
for(int i=1;i<=n;i++) if(rd[i]==0) q.push(i);
while(!q.empty()){
u=q.front(); q.pop();
for(int i=head[u];i>0;i=e[i].next){
v=e[i].to;
rd[v]--;
if(dp[v]<dp[u]+e[i].w){
dp[v]=dp[u]+e[i].w;
pre[v]=u;
}
if(rd[v]==0) q.push(v);
}
}
}
void bfs(int t){//反向求构成最长路径的所有点
int u,v;
queue<int> q;
q.push(t); vis[t]=true;
while(!q.empty()){
u=q.front(); q.pop();
for(int i=head2[u];i;i=e[i].next){
v=e[i].to;
if(dp[v]+e[i].w==dp[u] && !vis[v]){
q.push(v); vis[v]=true;
}
}
}
}
void print(int u){
if(u==0) return;
b[++cnt]=u;
print(pre[u]);
}
int main(){
int u,v,w;
cin>>n>>m; n++;
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
add(u,v,w); rd[v]++;
}
Top();
cout<<dp[n]<<endl;
bfs(n);
for(int i=1;i<=n;i++){
if(vis[i]) cout<<i<<" ";
}
return 0;
}