luoguP3953 逛公園 最短路計數 拓撲序
luoguP3953 逛公園
題目傳送門
分析1
作為一名標準的NOIP退役選手,果然過了一年之後仍然不會做這道題。
首先肯定先求最短路,一種思路是
表示鬆弛了
的最短路從起點走到
節點。
很容易寫出方程:
其中
表示的是這一回走到
的步數,減去原來的最短路
就是走到
的鬆弛步數。
由於最短路的性質,所以
所以這個
的轉移實際上形成了一張分層圖。我們從小到大列舉
這樣就可以保證轉移的拓撲有序。
但是要注意一種
的情況。這意味著
這條邊在最短路徑中。也就是說,對於所有的在最短路徑上的邊,都需要特殊考慮其拓撲序。
首先在沒有
邊的情況,最短路徑邊一定形成了一張
,到1的距離
就是他們的拓撲偏序。按照
排序即可轉移。
考慮
邊的情況。如果有
環,判斷環中的節點是不是合法的。合法定義為
,如果這樣的話,方案數一定無窮,輸出-1即可。否則的話,這個
環中的所有節點一定不會出現在我們方程的轉移中,可以不用管他們。
這個時候剩下的圖一定仍然是一張
。只不過我們不能僅僅按照
排序,考慮
相同的節點,還需要考慮
邊的順序。所以對於所有
邊做一遍拓撲排序,以
為第一關鍵字,
邊拓撲序為第二關鍵字重新排序即可。
複雜度
程式碼1
#include<bits/stdc++.h>
const int N = 1e5 + 10, M = 2e5 + 10, Nt = 131072, inf = 0x3f3f3f3f;
int ri() {
char c = getchar(); int x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
int n, q[N], d[N], rk[N], f[N], g[N], *D, id[N], T[Nt << 1], dp[51][N], K, P;
struct Edge {
int nx[M], pr[N], to[M], w[M], tp;
void add(int u, int v, int W) {to[++tp] = v; nx[tp] = pr[u]; pr[u] = tp; w[tp] = W;}
void adds(int u, int v, int w) {add(u, v, w); add(v, u, w);}
void Pre() {for(int i = 1;i <= n; ++i) pr[i] = 0; tp = 0;}
}G, R;
int min(int a, int b) {return D[a] < D[b] ? a : b;}
bool cmp(int a, int b) {return f[a] == f[b] ? rk[a] < rk[b] : f[a] < f[b];}
void Up(int i, int v) {for(T[i += Nt] = v;i >>= 1;) T[i] = min(T[i << 1], T[i << 1 | 1]);}
void Dij(const Edge &G, int st) {
for(int i = 0;i <= n; ++i) D[i] = inf;
D[st] = 0; Up(st, st);
for(;D[T[1]] != inf;) {
int u = T[1]; Up(u, 0);
for(int i = G.pr[u], v, w; i; i = G.nx[i])
if(D[v = G.to[i]] > (w = D[u] + G.w[i]))
D[v] = w, Up(v, v);
}
}
bool Topsort() {
int L = 1, R = 0;
for(int i = 1;i <= n; ++i)
if(!d[i])
q[++R] = i;
for(int u = q[L];L <= R; u = q[++L])
for(int i = G.pr[u]; i; i = G.nx[i])
if(!G.w[i] && !--d[G.to[i]])
q[++R] = G.to[i];
for(int i = 1;i <= R; ++i)
rk[q[i]] = i;
for(int i = 1;i <= n; ++i)
if(d[i] && f[i] + g[i] <= f[n] + K)
return false;
for(int i = 1;i <= n; ++i)
id[i] = i;
std::sort(id + 1, id + n + 1, cmp);
return true;
}
void Inc(int &a, int b) {a += b; if(a >= P) a -= P;}
void Dp() {
memset(dp, 0, sizeof(dp));
dp[0][id[1]] = 1;
for(int k = 0;k <= K; ++k)
for(int x = 1, u = id[1];x <= n; u = id[++x])
for(int i = G.pr[u], w, v; i; i = G.nx[i])
if((w = f[u] + k + G.w[i] - f[v = G.to[i]]) <= K)
Inc(dp[w][v], dp[k][u]);
}
int main() {
for(int C = ri();C--;) {
n = ri(); int m = ri(); K = ri(), P = ri();
G.Pre(); R.Pre();
for(int i = 1;i <= n; ++i)
d[i] = rk[i] = 0;
for(int u, v, w;m--
相關推薦
luoguP3953 逛公園 最短路計數 拓撲序
luoguP3953 逛公園
題目傳送門
分析1
作為一名標準的NOIP退役選手,果然過了一年之後仍然不會做這道題。 首先肯定先求最短路,一種思路是
f
[NOIP2017]逛公園 最短路圖 拓撲序DP
none img ble next lose spf 沒有 gist pop ~~~題面~~~
題解:
挺好的一道題。
首先我們將所有邊反向,跑出n到每個點的最短路,然後f[i][j]表示從i號節點出發,路徑長比最短路大j的方案數。
觀察到,如果圖中出現
洛谷3953 NOIP2017 逛公園 最短路圖+拓撲排序+dp
題目連結
題意:
給你一個n個點m條邊的有向帶權圖,設1號點到n號點的最短路是dis,給你一個k(k<=50),求所有1到n的路徑中長度不超過dis+k的數量。
題解:
顯然我們要先處理出最短路,以後再也不會寫SPFA了,因為NOI2018卡了SP
【題解】洛谷P3953[NOIP2017]逛公園 最短路+拓撲排序+計數類DP
題目連結
學習了大佬題解。根據大佬的講解,把對應部分分的程式碼打到一起了。(有點臃腫)
#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<
【NOIP2017】逛公園 最短路+DP
() next sizeof truct c++ pre 長度 div 分層圖 誒,去年場上不會處理$0$的環,只拿了$60$有點可惜。
我們先不管邊邊權為$0$的邊。
我們先跑一次最短路,令$dis[u]$表示從$1$至$u$的最短路的長度。
那麽根據題目的要求,從
p1242 字典序最小的拓撲序
題目
描述 Description 給定一個有N個節點的有向圖(編號為0~N-1),求其拓撲排序的最小字典序。 輸入格式 Input Format 第一行兩個整數 N和M,表示圖有N個點,M條邊。 接下來M行,2個整數ui和vi,表示ui到vi有條有向邊。 輸出格式 Output
2018.11.07【NOIP2017】【洛谷P3953】逛公園(DP)(魔改最短路計數)
傳送門
解析:
首先這鬼畜的最短路肯定你是要自己跑一遍的。
但是我是在反圖上面跑。。
因為我的DP策略表示在當前點
u
u
P1144 最短路計數
prior print 如果 cstring 不同的 priority %d 2個 name
題目描述
給出一個N個頂點M條邊的無向無權圖,頂點編號為1~N。問從頂點1開始,到其他每個點的最短路有幾條。
輸入輸出格式
輸入格式:
輸入第一行包含2個正整數
洛谷 P1144 最短路計數
-- 多少 pop fine www pty class 接下來 輸出格式 題目描述
給出一個N個頂點M條邊的無向無權圖,頂點編號為1~N。問從頂點1開始,到其他每個點的最短路有幾條。
輸入輸出格式
輸入格式:
輸入第一行包含2個正整數N,M,為圖的頂點數與邊
洛谷——P1144 最短路計數
lin can 初始化 onclick 初始 () clas har 變形 P1144 最短路計數
題目描述
給出一個N個頂點M條邊的無向無權圖,頂點編號為1~N。問從頂點1開始,到其他每個點的最短路有幾條。
輸入輸出格式
輸入格式:
輸入第一行包含2個正整
BZOJ 2118 墨墨的不等式 數論 + 最短路 + 計數
ace ret space log const 最短 fin push bzoj
1 #include<bits/stdc++.h>
2 #define LL long long
3 const LL INF = 50000000000000000ll;
最短路計數 [LuoGu P 1144]
memset == insert const size node 分享 pan 備忘 題目大意 :
給出一個N個頂點M條邊的無向無權圖,頂點編號為1~N。問從頂點1開始,到其他每個點的最短路有幾條。
大水題 , 為了備忘 , 還是記下來吧 .
不推方程了,,,,i
洛谷P1144——最短路計數
string class 代碼 main oid iostream mes include 計數 題目:https://www.luogu.org/problemnew/show/P1144
spfa跑最短路的同時記錄cnt數組表示到達方案數。
代碼如下:
#includ
武漢大學校賽 tarjan+求最長鏈+拓撲排序
unique void scanf ont bool back 校賽 using --
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
stack<int>s;
ve
【luogu P1144 最短路計數】 題解
color style ref bsp vector cst itl () col 題目鏈接:https://www.luogu.org/problemnew/show/P1144
1 #include <iostream>
2 #include &
洛谷 P1144 最短路計數 解題報告
++ 報告 CA amp ret 正整數 std 最短路 www P1144 最短路計數
題目描述
給出一個\(N\)個頂點\(M\)條邊的無向無權圖,頂點編號為\(1-N\)。問從頂點1開始,到其他每個點的最短路有幾條。
輸入輸出格式
輸入格式:
第一行包含2個正整數\(
洛谷_P1144_最短路計數
gin lis ron 大於 font har bottom 覆蓋 otto 題目大意:
給出一個 N 個頂點 M 條邊的無向無權圖,頂點編號為 1-N。問從頂點 1 開始,到其他每個點的最短路有幾條。
題解:
更新邊長的時候如果大於號就覆蓋,有相同最短路徑就相
【洛谷習題】最短路計數
代碼 main tar name tex 並且 set getchar() eof 水題鏈接:https://www.luogu.org/problemnew/show/P1144
這道題就是很水啊,水到我居然不用最短路算法就做了出來。因為每條邊的權值都為1,最
最短路計數
class sizeof cst get 更新 math truct turn 操作 題目:
給出一個N個頂點M條邊的無向無權圖,頂點編號為1−N。問從頂點1開始,到其他每個點的最短路有幾條。