LS 22 Longest path on DAG(最短路+SPFA)
原创
©著作权归作者所有:来自51CTO博客作者mb63dd04d4d8713的原创作品,请联系作者获取转载授权,否则将追究法律责任
Longest path on DAG
G.
Input
n, m, which denote the number of vertices and edges.
m lines contains two integer ai, bi, which denote edge ai→bi.
(1≤n≤105,1≤m≤106,1≤ai<bi≤n)
Ouptut
l, which denotes the length of longest path.
l+1
Sample input
Sample output
思路:建边,建个源点0和汇点,然后依次在源点和汇点与中间所有点连边。求源点和汇点的最长路就是答案。
本题需要从汇点往源点做最短路
#include<iostream>
#include<cstring>
using namespace std;
const int mm=6e6+9;
int ver[mm],next[mm],head[mm],edge,q[mm],dis[mm],fa[mm];
bool vis[mm];
int n,m;
void prepare()
{
for(int i=0;i<n+2;i++)head[i]=-1,fa[i]=-1;edge=0;
}
void add(int aa,int bb)
{
ver[edge]=bb;next[edge]=head[aa];head[aa]=edge++;
}
int spfa()
{ memset(dis,-1,sizeof(dis));
memset(vis,0,sizeof(vis));
int l=0,r=1,u,v;
q[l]=0;vis[0]=1;dis[0]=0;
while(l^r)
{u=q[l++];l%=mm;vis[u]=0;
for(int i=head[u];i!=-1;i=next[i])
{ v=ver[i];
if(dis[v]<dis[u]+1)
{
dis[v]=dis[u]+1;fa[v]=u;
if(!vis[v])
q[r++]=v,r%=mm,vis[v]=1;
}
else if(dis[v]==dis[u]+1&&fa[v]>u)fa[v]=u;
}
}
cout<<dis[n+1]-2<<"\n";
int pos=0,zz=fa[n+1];
while(zz!=-1)
{
ver[pos++]=zz;
zz=fa[zz];
}
for(int i=0;i<pos-2;i++)
cout<<ver[i]<<" ";
cout<<ver[pos-2]<<"\n";
}
int main()
{
while(cin>>n>>m)
{ int a,b;
prepare();
for(int i=0;i<m;i++)
{
cin>>a>>b;add(b,a);///建反向边
}
for(int i=1;i<=n;i++)
add(0,i),add(i,n+1);
spfa();
}
}