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

4 4
1 2
1 3
2 4
3 4

Sample output

2
1 2 4


思路:建边,建个源点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();
}
}