這個題不難,就是先trajan縮點減小點數和邊數的規模,然後在縮完點的圖上跑dp即可。注意要用toposort解決dp後效性(或者是使用記憶化搜尋)。
code
#include#include#include#include#define maxn 10010
#define maxm 500100
int n, m, idx;
int head_b[maxn], cnt_b;
int head_r[maxn], cnt_r;
int dfn[maxn], low[maxn];
int bel[maxn], flag[maxn];
int in[maxn], val[maxn];
int f[maxn];
struct node_basic edge_b[maxm];
struct node_rebuild edge_r[maxm];
inline int read(void) while (ch < '0' || ch > '9');
do while (ch >= '0' && ch <= '9');
return f * x;
}class stack
inline void pop(void)
inline int top(void)
} stk;
class queue
inline int front(void)
inline void pop(void)
inline bool empty(void)
} q;
inline int _min(int x, int y)
inline int _max(int x, int y)
inline void add_edge_basic(int x,int y)
inline void add_edge_rebuild(int x,int y)
void tarjan(int k)
if(dfn[k]==low[k])
}return;
}int toposort(void)
while(!q.empty())
}int res = 0;
for (int i = 1; i <= n; ++i)
res = _max(res, f[i]);
return res;
}int main()
for (int i = 1; i <= n; ++i)
if(!dfn[i]) tarjan(i);
for (int i = 1; i <= m; ++i)
printf("%d\n", toposort());
return 0;
}
tarjan dp P3387 模板 縮點
可以多次走乙個點或一條邊,但只計算一次點權,意味著我們需要進行縮點 tarjan進行求強聯通分量主要記錄dfn i low i 以及維護que記錄走過的點 通過後向邊和樹枝邊對low值的更新,當dfn i low i 時,就出現了強連通分量,可以進行縮點操作 在縮點後,重新建圖,然後就可以通過dp ...
P3387 模板 縮點
r es ul tresult result h yp erli nk hyperlink hyperl ink de scri ptio ndescription descri ptio n 給定一張n nn個點,m mm條邊的有向圖,點有點權 找出一條路徑使得經過的點的權值和最大,點和邊可以重複...
P3387 模板 縮點
縮點 dp 給定乙個n個點m條邊有向圖,每個點有乙個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。允許多次經過一條邊或者乙個點,但是,重複經過的點,權值只計算一次。輸入格式 第一行,n,m 第二行,n個整數,依次代表點權 第三至m 2行,每行兩個整數u,v,表示u v有一條有...