SPFA求最大路

求最長路可以將邊權乘以-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);
    dis2[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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章