求最长路可以将边权乘以-1,然后求最短路即可,之后最短路取相反数就是最大路。
SPFA板子
vector<int>v[MAX_N],w[MAX_N];
int have[MAX_N],dis[MAX_N];
void spfa(int be){
int i;
queue<skt>q;
skt k;
have[be]=true;
k.x=be;
k.d=0;
q.push(k);
dis[be]=0;
while(!q.empty()){
skt now=q.front();
q.pop();
have[now.x]=false;
for(i=0;i<v[now.x].size();i++){
int to=v[now.x][i];
int cost=w[now.x][i];
if(dis[to]>dis[now.x]+cost){
dis[to]=dis[now.x]+cost;
if(!have[to]){
skt t;
t.x=to;
t.d=dis[to];
q.push(t);
have[to]=true;
}
}
}
}
}
P3119 USACO15JAN草鉴定Grass Cownoisseur
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int MAX_N=101000;
const int INF=0x3f3f3f3f;
int ans;//强连通分量的个数
int low[MAX_N],num[MAX_N],cnt;
int sum[MAX_N];
int stack[MAX_N],top;
int vis[MAX_N];
vector<int>v[MAX_N],sv[MAX_N],sw[MAX_N],tv[MAX_N],tw[MAX_N];
void dfs(int now){
int i;
stack[top++]=now;
low[now]=num[now]=++cnt;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(!num[to]){
dfs(to);
low[now]=min(low[now],low[to]);
}
else if(!vis[to])
low[now]=min(low[now],num[to]);
}
if(low[now]==num[now]){
ans++;
while(1){
int to=stack[--top];
vis[to]=ans;
if(now==to)
break;
}
}
}
void tarjan(int n){
int i,j;
ans=cnt=top=0;
memset(vis,0,sizeof(vis));
memset(num,0,sizeof(num));
memset(low,0,sizeof(low));
for(i=1;i<=n;i++){
if(!num[i])
dfs(i);
}
for(i=1;i<=n;i++){
sum[vis[i]]++;
for(j=0;j<v[i].size();j++){
int to=v[i][j];
if(vis[i]!=vis[to]){
sv[vis[i]].push_back(vis[to]);
tv[vis[to]].push_back(vis[i]);
}
}
}
}
int dis1[MAX_N],dis2[MAX_N];
bool have[MAX_N];
struct skt{
int x,d;
friend bool operator <(skt a,skt b){
return a.d<b.d;
}
};
void spfa1(int be){
int i;
queue<skt>q;
skt k;
have[be]=true;
k.x=be;
k.d=0;
q.push(k);
dis1[be]=0;
while(!q.empty()){
skt now=q.front();
q.pop();
have[now.x]=false;
for(i=0;i<sv[now.x].size();i++){
int to=sv[now.x][i];
int cost=sw[now.x][i];
if(dis1[to]>dis1[now.x]+cost){
dis1[to]=dis1[now.x]+cost;
if(!have[to]){
skt t;
t.x=to;
t.d=dis1[to];
q.push(t);
have[to]=true;
}
}
}
}
}
void spfa2(int be){
int i;
queue<skt>q;
skt k;
have[be]=true;
k.x=be;
k.d=0;
q.push(k);
dis2[be]=0;
while(!q.empty()){
skt now=q.front();
q.pop();
have[now.x]=false;
for(i=0;i<tv[now.x].size();i++){
int to=tv[now.x][i];
int cost=tw[now.x][i];
if(dis2[to]>dis2[now.x]+cost){
dis2[to]=dis2[now.x]+cost;
if(!have[to]){
skt t;
t.x=to;
t.d=dis2[to];
q.push(t);
have[to]=true;
}
}
}
}
}
int main(void){
int n,m,i,j,a,b;
scanf("%d%d",&n,&m);
for(i=0;i<m;i++){
scanf("%d%d",&a,&b);
v[a].push_back(b);
}
tarjan(n);
for(i=1;i<=ans;i++){
for(j=0;j<sv[i].size();j++){
int to=sv[i][j];
sw[i].push_back(-sum[to]);
}
for(j=0;j<tv[i].size();j++){
int to=tv[i][j];
tw[i].push_back(-sum[to]);
}
}
memset(have,0,sizeof(have));
memset(dis1,INF,sizeof(dis1));
spfa1(vis[1]);
memset(have,0,sizeof(have));
memset(dis2,INF,sizeof(dis2));
spfa2(vis[1]);
int abc=sum[vis[1]];
for(i=1;i<=ans;i++){
if(dis1[i]!=INF)
dis1[i]=-dis1[i]+abc;
if(dis2[i]!=INF)
dis2[i]=-dis2[i]+abc;
}
int res=abc;
for(i=1;i<=ans;i++){
for(j=0;j<sv[i].size();j++){
int to=sv[i][j];
if(dis2[i]!=INF&&dis1[to]!=INF){
res=max(res,dis1[to]+dis2[i]-abc);
}
}
}
cout<<res<<"\n";
return 0;
}