拓扑求有向图最长路或最短路

这道题是先用Tarjan缩点,告诉起点,然后拓扑求无向图最长路径

然而我一心以为只需要从起点开始拓扑就行了,其他不是路径上的点与s的正确路径又无关,但是这是错误的,

因为拓扑加点的条件是入度为0,不把那条边去掉的话,正确路径上的点也出不来,所以错了呀....

题目:https://www.luogu.com.cn/problem/P2656

代码:

拓扑求有向图最长路或最短路
#include<iostream>
#include<string>
#include<stack>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<map>
#include<unordered_map>
#include<vector>
#include<iomanip>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 6e5 + 100;
const int maxm = 6e5 + 100;
inline int r() {
    int f = 1, num = 0;
    char ch = getchar();
    while (0 == isdigit(ch)) { if (ch == '-')f = -1; ch = getchar(); }
    while (0 != isdigit(ch)) num = (num << 1) + (num << 3) + ch - '0', ch = getchar();
    return num * f;
}
struct edge {
    int from, to, next, w;
    double xishu;
}edge[maxm];
int tot1, hd[maxn];
void add_edge(int f, int to, int w, double x) {
    ++tot1;
    edge[tot1] = { f,to,hd[f],w,x };
    hd[f] = tot1;
}
struct E {
    int to, next, w;
}e[maxn];
int tot2, hd2[maxn];
void adde(int f, int to, int w) {
    tot2++;
    e[tot2] = { to,hd2[f],w };
    hd2[f] = tot2;
}
int fcn[maxn], low[maxn], vis[maxn], numcol, col[maxn], val[maxn], dis[maxn], du[maxn];
int cnt;
stack<int>S;
void Trajan(int rt) {

    fcn[rt] = low[rt] = ++cnt;
    vis[rt] = 1;
    S.push(rt);
    for (int i = hd[rt]; i; i = edge[i].next) {
        int v = edge[i].to;
        if (!fcn[v]) {
            Trajan(v);
            low[rt] = min(low[v], low[rt]);
        }
        else if (vis[v]) {
            low[rt] = min(low[rt], fcn[v]);
        }
    }
    if (low[rt] == fcn[rt]) {
        numcol++;
        //cout << "*" << numcol << endl;
        while (1) {
            int t = S.top(); S.pop();
            col[t] = numcol;
            vis[t] = 0;
            //cout << t << " ";
            if (t == rt)break;
        }
        //cout << endl;
    }
}
//int tuopu() {//错误的代码
//    queue<int>Q;
//    Q.push(col[s]);
//    int res = dis[st];
//    while (!Q.empty()) {
//        int t = Q.front(); Q.pop();
//        dis[t] += val[t];
//        res = max(res, dis[t]);
//        for (int i = hd2[t]; i; i = e[i].next) {
//            int v = e[i].to, w = e[i].w;
//            du[v]--;
//            //cout<<"&"<<t<<" "<< v << w << endl;
//            if (du[v] == 0)Q.push(v);
//            dis[v] = max(dis[v], dis[t] + w);
//        }
//    }
//    return res;
//}
int s;
int tuopu()
{
    queue<int>q;
    for (int i = 1; i <= numcol; i++)
    {
        if (!du[i])
            q.push(i);
        dis[i] = -0x7fffffff;
    }
    int ans = -0x7fffffff;
    dis[col[s]] = val[col[s]];
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int i = hd2[u]; i; i = e[i].next)
        {
            int v = e[i].to;
            dis[v] = std::max(dis[u] + e[i].w + val[v], dis[v]);
            du[v]--;
            if (!du[v])
                q.push(v);
        }
    }
    for (int i = 1; i <= numcol; i++)
        ans = std::max(ans, dis[i]);
    return ans;
}

int n, m;
int main() {
    //freopen("test.txt", "r", stdin);
    n = r(), m = r();
    for (int i = 1; i <= m; i++) {
        int st = r(), ed = r(), w = r();
        //cout <<"mm"<< st << " " << ed<<endl;
        double x; scanf("%lf", &x);
        add_edge(st, ed, w, x);
    }
    for (int i = 1; i <= n; i++) {
        if (!fcn[i]) {
            Trajan(i);
        }
    }
    for (int i = 1; i <= m; i++) {
        int u = edge[i].from, v = edge[i].to, w = edge[i].w;
        double x = edge[i].xishu;
        if (col[u] == col[v]) {
            while (w) {
                val[col[u]] += w;
                w *= x;
            }
        }
        else {
            //cout << u << v << endl;
            adde(col[u], col[v], w);
            du[col[v]]++;
        }
    }
    s = r();
    cout << tuopu() << endl;
    return 0;
}
View Code

 

上一篇:Attention, Suggestion and Annotation: A Deep Active Learning Framework for Biomedical Image Segmenta


下一篇:Java实现 LeetCode 352 将数据流变为多个不相交区间