P1807 最长路

spfa

const int N=1510;
vector<PII> g[N];
LL dist[N];
bool vis[N];
int n,m;

void spfa()
{
    memset(dist,-0x3f,sizeof dist);
    queue<int> q;
    q.push(1);
    dist[1]=0;

    while(q.size())
    {
        int t=q.front();
        q.pop();
        vis[t]=false;

        for(int i=0;i<g[t].size();i++)
        {
            int j=g[t][i].fi,w=g[t][i].se;
            if(dist[j] < dist[t] + w)
            {
                dist[j]=dist[t]+w;
                if(!vis[j])
                {
                    q.push(j);
                    vis[j]=true;
                }
            }
        }
    }
}

int main()
{
    cin>>n>>m;

    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        g[a].push_back({b,c});
    }

    spfa();

    if(dist[n] < -5e9) cout<<-1<<endl;
    else cout<<dist[n]<<endl;
    //system("pause");
}

注意到原图为DAG,不由联想到拓扑排序,至于最长路只需dp就可以了

  • 注意只能初始化1号店距离为0,因为是求1号点到n号点的最长路

类似于刷表法

const int N=1510;
vector<PII> g[N];
int dist[N];
int din[N];
int n,m;

void topo()
{
    memset(dist,-0x3f,sizeof dist);
    queue<int> q;

    for(int i=1;i<=n;i++)
        if(!din[i])
            q.push(i);

    dist[1]=0;

    while(q.size())
    {
        int t=q.front();
        q.pop();

        for(int i=0;i<g[t].size();i++)
        {
            int j=g[t][i].fi,w=g[t][i].se;

            if(dist[j] < dist[t] + w) dist[j]=dist[t]+w;

            if(--din[j] == 0) q.push(j);
        }
    }
}

int main()
{
    cin>>n>>m;

    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        g[a].pb({b,c});
        din[b]++;
    }

    topo();

    if(dist[n] < -1e9) puts("-1");
    else cout<<dist[n]<<endl;
    //system("pause");
}
posted @ 2020-09-01 18:01  Dazzling!  阅读(159)  评论(0编辑  收藏  举报