洛谷P3953 [NOIP 2017 提高組] 逛公園

洛谷P3953 [NOIP 2017 提高組] 逛公園

洛谷題目傳送門

題目背景

NOIP2017 D1T3

題目描述

策策同學特別喜歡逛公園。公園可以看成一張 N N N 個點 M M M 條邊構成的有向圖,且沒有 自環和重邊。其中 1 1 1 號點是公園的入口, N N N 號點是公園的出口,每條邊有一個非負權值, 代表策策經過這條邊所要花的時間。

策策每天都會去逛公園,他總是從 1 1 1 號點進去,從 N N N 號點出來。

策策喜歡新鮮的事物,它不希望有兩天逛公園的路線完全一樣,同時策策還是一個 特別熱愛學習的好孩子,它不希望每天在逛公園這件事上花費太多的時間。如果 1 1 1 號點 到 N N N 號點的最短路長為 d d d,那么策策只會喜歡長度不超過 d + K d + K d+K 的路線。

策策同學想知道總共有多少條滿足條件的路線,你能幫幫它嗎?

為避免輸出過大,答案對 P P P 取模。

如果有無窮多條合法的路線,請輸出 ? 1 -1 ?1

輸入格式

第一行包含一個整數 T T T, 代表數據組數。

接下來 T T T 組數據,對于每組數據: 第一行包含四個整數 N , M , K , P N,M,K,P N,M,K,P,每兩個整數之間用一個空格隔開。

接下來 M M M 行,每行三個整數 a i , b i , c i a_i,b_i,c_i ai?,bi?,ci?,代表編號為 a i , b i a_i,b_i ai?,bi? 的點之間有一條權值為 c i c_i ci? 的有向邊,每兩個整數之間用一個空格隔開。

輸出格式

輸出文件包含 T T T 行,每行一個整數代表答案。

輸入輸出樣例 #1

輸入 #1

2
5 7 2 10
1 2 1
2 4 0
4 5 2
2 3 2
3 4 1
3 5 2
1 5 3
2 2 0 10
1 2 0
2 1 0

輸出 #1

3
-1

說明/提示

【樣例解釋1】

對于第一組數據,最短路為 3 3 3 1 → 5 , 1 → 2 → 4 → 5 , 1 → 2 → 3 → 5 1\to 5, 1\to 2\to 4\to 5, 1\to 2\to 3\to 5 15,1245,1235 3 3 3 條合法路徑。

【測試數據與約定】

對于不同的測試點,我們約定各種參數的規模不會超過如下

測試點編號 T T T N N N M M M K K K是否有 0 0 0
1 1 1 5 5 5 5 5 5 10 10 10 0 0 0
2 2 2 5 5 5 10 3 10^3 103 2 × 10 3 2\times 10^3 2×103 0 0 0
3 3 3 5 5 5 10 3 10^3 103 2 × 10 3 2\times 10^3 2×103 50 50 50
4 4 4 5 5 5 10 3 10^3 103 2 × 10 3 2\times 10^3 2×103 50 50 50
5 5 5 5 5 5 10 3 10^3 103 2 × 10 3 2\times 10^3 2×103 50 50 50
6 6 6 5 5 5 10 3 10^3 103 2 × 10 3 2\times 10^3 2×103 50 50 50
7 7 7 5 5 5 10 5 10^5 105 2 × 10 5 2\times 10^5 2×105 0 0 0
8 8 8 3 3 3 10 5 10^5 105 2 × 10 5 2\times 10^5 2×105 50 50 50
9 9 9 3 3 3 10 5 10^5 105 2 × 10 5 2\times 10^5 2×105 50 50 50
10 10 10 3 3 3 10 5 10^5 105 2 × 10 5 2\times 10^5 2×105 50 50 50

對于 100 % 100\% 100% 的數據, 1 ≤ P ≤ 10 9 1 \le P \le 10^9 1P109 1 ≤ a i , b i ≤ N 1 \le a_i,b_i \le N 1ai?,bi?N 0 ≤ c i ≤ 1000 0 \le c_i \le 1000 0ci?1000

數據保證:至少存在一條合法的路線。


  • 2019.8.30 增加了一組 hack 數據 by @skicean
  • 2022.7.21 增加了一組 hack 數據 by @djwj233

思路詳解

最短路

首先由于它要求最短路徑,由于害怕被卡,所以保險起見我們采用dijkstra求解最短路。

void dij(ll o){//dijkstra標準模板,o為起點memset(dis,0x3f,sizeof(dis));//記得賦初值!!!memset(vis,0,sizeof(vis));queue<ll>q;q.push(o);vis[o]=1;dis[o]=0;while(!q.empty()){ll u=q.front();q.pop();vis[u]=0;for(ll i=h[u];i;i=ne[i]){ll v=to[i];if(dis[v]>dis[u]+w[i]){dis[v]=dis[u]+w[i];if(!vis[v]){vis[v]=1;q.push(v);}}}}
}

深搜求解

我們最多有 k k k的相差,考慮依次枚舉實際相差的 q q q(否則可能計算不完全),采用記憶化深搜求解。具體步驟如下:

  1. 定義:記憶化數組 f u , j f_{u,j} fu,j?為到 u u u點, q q q剩下 j j j的方案數。 d f s ( u , q ) dfs(u,q) dfs(u,q)同理
  2. 邊界條件: f n , 0 = 1 f_{n,0}=1 fn,0?=1
  3. 狀態轉移:令 d = q ? ( d i s u + w i ? d i s v ) d=q-(dis_{u}+w_{i}-dis_{v}) d=q?(disu?+wi??disv?)即消耗了當前的 q q q后的值,若 d < 0 d<0 d<0則直接退出。
    否則累加答案: f u , j + = d f s ( v , d ) f_{u,j}+=dfs(v,d) fu,j?+=dfs(v,d)

但是,我們發現,題目中說可能有無數解的情況,肯定是有0環,那如何判斷是否有0環呢?,考慮定于數組 v i u , q vi_{u,q} viu,q?,表示是否訪問過狀態 u , q {u,q} u,q,若在深搜訪問狀態 u , q {u,q} u,q v i u , q = = 1 vi_{u,q}==1 viu,q?==1,那說明跑了一圈跑回來了,那一定有0環,標記并退出。

**int f[N][56],fl=0,vi[N][56];
int dfs(int u,int q){if(vi[u][q]){//已經訪問過這種狀態,有0環fl=1;return 0;}if(f[u][q]!=-1)return f[u][q];//記憶化深搜vi[u][q]=1;//標記f[u][q]=0;//由于f數組初始值為-1,將其賦值為0for(int i=h[u];i;i=ne[i]){int v=to[i];int d=q-(dis[u]+w[i]-dis[v]);//消耗后的狀態if(d<0)continue;f[u][q]=(f[u][q]+dfs(v,d))%p;//求和,記得取模if(fl==1)return 0;//dfs(v,d)中fl變成了1也要退出}if(u==n&&q==0)f[u][q]=1;//邊界vi[u][q]=0;//回溯return f[u][q];
}**

反向跑圖

我們將代碼提交上去,發現有些數據是錯的。而且錯誤數據都是錯誤輸出-1,即0環判斷錯誤。這是為何?我們發現,如果一旦有0環我們的深搜便會返回-1,但其實有可能根本不會經過這個0環,那如何規避這個錯誤呢?我們直接反向跑圖,這樣亂跑的情況就會被規避掉。但要注意,狀態轉移變為了: d = q ? ( d i s v + w i ? d i s u ) d=q-(dis_{v}+w_{i}-dis_{u}) d=q?(disv?+wi??disu?),因為原來是 v ? > u v->u v?>u,現在變為了 u ? > v u->v u?>v

完整代碼

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=2e5+4;
ll n,m,t,k,p;
ll h[N],to[N],w[N],ne[N],tot;
void add(ll u,ll v,ll d){tot++;to[tot]=v;w[tot]=d;ne[tot]=h[u];h[u]=tot;
}
struct edge{ll x,y,z;
}a[N];
ll dis[N],vis[N];
void dij(ll o){//dijkstra標準模板,o為起點memset(dis,0x3f,sizeof(dis));//記得賦初值!!!memset(vis,0,sizeof(vis));queue<ll>q;q.push(o);vis[o]=1;dis[o]=0;while(!q.empty()){ll u=q.front();q.pop();vis[u]=0;for(ll i=h[u];i;i=ne[i]){ll v=to[i];if(dis[v]>dis[u]+w[i]){dis[v]=dis[u]+w[i];if(!vis[v]){vis[v]=1;q.push(v);}}}}
}
ll ans;
ll f[N][56],fl=0,vi[N][56];
ll dfs(ll u,ll q){if(vi[u][q]){//已經訪問過這種狀態,有0環fl=1;return 0;}if(f[u][q]!=-1)return f[u][q];//記憶化深搜vi[u][q]=1;//標記f[u][q]=0;//由于f數組初始值為-1,將其賦值為0for(ll i=h[u];i;i=ne[i]){ll v=to[i];ll d=q-(dis[v]+w[i]-dis[u]);//消耗后的狀態if(d<0)continue;f[u][q]=(f[u][q]+dfs(v,d))%p;//求和,記得取模if(fl==1)return 0;//dfs(v,d)中fl變成了1也要退出}if(u==1&&q==0)f[u][q]=1;//邊界vi[u][q]=0;//回溯return f[u][q];
}
int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>t;for(ll cas=1;cas<=t;cas++){cin>>n>>m>>k>>p;fl=0;tot=0;//鏈式前向星清空只需要清空tot與hmemset(h,0,sizeof(h));for(ll i=1;i<=m;i++){ll x,y,z;cin>>x>>y>>z;a[i]={x,y,z};//將邊保存下來}for(ll i=1;i<=m;i++){ll x=a[i].x,y=a[i].y,z=a[i].z;add(x,y,z);//正向建邊}dij(1);//正向跑最短路ans=0;tot=0;//清空memset(h,0,sizeof(h));for(ll i=1;i<=m;i++){//方向見圖ll x=a[i].x,y=a[i].y,z=a[i].z;add(y,x,z);}memset(f,-1,sizeof(f));memset(vi,0,sizeof(vi));for(ll i=0;i<=k;i++){ans=(ans+dfs(n,i))%p;if(fl)break;}if(fl)cout<<-1<<'\n';else cout<<ans<<'\n';}return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88073.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88073.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88073.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue3+TypeScript+Element Plus 表格展開行優化方案

在 Vue3 TypeScript Element Plus 項目中優化表格展開行的內存使用&#xff0c;主要從 渲染優化、數據管理 和 內存回收 三方面入手。以下是最佳實踐和完整解決方案&#xff1a; 1. 懶加載展開內容&#xff08;核心優化&#xff09; 只當行展開時才渲染內容&#xff0c;避免…

OpenCV——直方圖與匹配

直方圖與匹配 一、直方圖簡介二、直方圖統計三、直方圖比較四、直方圖均衡化五、自適應的直方圖均衡化六、直方圖反向投影七、模板匹配 一、直方圖簡介 圖像直方圖&#xff08;Histogram&#xff09;是一種頻率分布圖&#xff0c;它描述了不同強度值在圖像中出現的頻率。圖像直…

通義大模型在文檔自動化處理中的高效部署指南(OCR集成與批量處理優化)

1. 傳統OCR解決方案常面臨識別精度低、版面分析能力弱、處理效率瓶頸等問題。通義大模型憑借其多模態理解和生成能力&#xff0c;為文檔處理領域帶來革命性突破。本文將深入探討如何高效部署通義大模型實現端到端的文檔自動化處理&#xff0c;特別聚焦OCR集成與批量處理優化兩…

Ubuntu20.04通過ssh協議配置遠程終端

一、在目標計算機&#xff08;即被連接的計算機&#xff09;上操作&#xff1a; 1、安裝 OpenSSH 服務器&#xff1a; sudo apt update sudo apt install openssh-server3、啟動并設置 SSH 服務開機自啟&#xff1a; sudo systemctl enable --now ssh二、在源計算機&#xf…

《HTTP權威指南》 第7章 緩存

帶著問題學習&#xff1a; 緩存如何提高性能如何衡量緩存的有效性緩存置于何處作用最大HTTP如何保持緩存副本的新鮮度緩存如何與其他緩存及服務器通信 web緩存是可以自動保存常見文檔副本的HTTP設備。 緩存優點 減少冗余的數據傳輸&#xff0c;節省網絡費用緩解網絡瓶頸問題&…

第十三章 模板

函數模板 函數模板使用 函數模板注意事項 自動類型推導&#xff0c;必須推導出一致的數據類型T,才可以使用 模板必須要確定出T的數據類型&#xff0c;才可以使用 普通函數和函數模板的類型轉化 普通函數隱式類型轉化&#xff08;char轉int&#xff09; 函數模板正常使用不會發生…

云計算-專有網絡VPC

&#x1f310; 什么是 VPC&#xff1f;&#xff08;Virtual Private Cloud&#xff09; VPC&#xff08;Virtual Private Cloud&#xff0c;虛擬私有云&#xff09; 是公有云服務商提供的一種網絡隔離服務&#xff0c;允許用戶在云中創建一個邏輯隔離的私有網絡環境。你可以在這…

關于*gin.Context的理解

關于*gin.Context的理解 作為初學者&#xff0c;在學習go語言用gin開發web時&#xff0c;我對*gin.Context感到困惑。本文章以自我總結為主&#xff0c;大部分為來自詢問ai后的總結&#xff0c;如有問題歡迎指出。 *gin.Context可以理解為一個gin框架的上下文對象指針&#x…

Qt中的OpenGL (6)[坐標系統]

文章目錄 文章說明學習目標目錄結構坐標系統局部空間世界空間觀察空間裁剪空間正射投影矩陣透視投影矩陣組合進入3D世界頂點數據著色器設置數據矩陣設置文章說明 本文是學習OpenGL的筆記,主要參考大神JoeyDeVries的LearnOpenGL第八課《坐標系統》,并將教程中的代碼基于Qt進行…

Spring Aop @After (后置通知)的使用場景?

核心定義 After 是 Spring AOP 中的另一種通知&#xff08;Advice&#xff09;類型&#xff0c;通常被稱為“后置通知”或“最終通知”。 它的核心作用是&#xff1a; 無論目標方法是正常執行完成&#xff0c;還是在執行過程中拋出了異常&#xff0c;After 通知中的代碼 總是…

UNet改進(4):交叉注意力(Cross Attention)-多模態/多特征交互

在計算機視覺領域&#xff0c;UNet因其優異的性能在圖像分割任務中廣受歡迎。本文將介紹一種改進的UNet架構——UNetWithCrossAttention&#xff0c;它通過引入交叉注意力機制來增強模型的特征融合能力。 1. 交叉注意力機制 交叉注意力(Cross Attention)是一種讓模型能夠動態地…

C#里從CSV文件加載BLOB數據字段到數據庫的處理

大量的數據保存在CSV文件, 當需要把這些數據加載到數據庫,然后使用數據庫來共享出去。 就需要把CSV文件導入數據庫, 怎么樣快速地把CSV文件導入數據庫呢? 這個就需要使用類MySqlBulkLoader,它是mariadb數據庫快速導入的方式。 一般使用SQL語句導入是10秒,那么使用這種方…

【后端】負載均衡

長期不定期更新補充。 定義 負載均衡&#xff08;Load Balancing&#xff09;是指將來自客戶端的請求合理分發到多個服務器或服務節點&#xff0c;以提高系統性能、可用性與可靠性。 分工 前端不做負載均衡&#xff0c;前端只發請求&#xff0c;不知道請求去哪臺服務器。 負…

記錄一次:Java Web 項目 CSS 樣式/圖片丟失問題:一次深度排查與根源分析

記錄一次&#xff1a;Java Web 項目 CSS 樣式/圖片丟失問題&#xff1a;一次深度排查與根源分析 **記錄一次&#xff1a;Java Web 項目 CSS 樣式丟失問題&#xff1a;一次深度排查與根源分析****第一層分析&#xff1a;資源路徑問題****第二層分析&#xff1a;服務端跳轉邏輯**…

torchmd-net開源程序是訓練神經網絡潛力

?一、軟件介紹 文末提供程序和源碼下載 TorchMD-NET 提供最先進的神經網絡電位 &#xff08;NNP&#xff09; 和訓練它們的機制。如果有多個 NNP&#xff0c;它可提供高效、快速的實現&#xff0c;并且它集成在 GPU 加速的分子動力學代碼中&#xff0c;如 ACEMD、OpenMM 和 …

在Docker上安裝Mongo及Redis-NOSQL數據庫

應用環境 Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-139-generic x86_64) Docker version 28.1.1, build 4eba377 文章目錄 一、部署Mongo1. 拉取容器鏡像2. 生成Run腳本2.1 準備條件2.2 參數解讀2.3 實例腳本 3. 實例操作3.1 Mongo bash控制臺3.2 庫表操作 4. MongoDB Compass (G…

Java 編程之責任鏈模式

一、什么是責任鏈模式&#xff1f; 責任鏈模式&#xff08;Chain of Responsibility Pattern&#xff09; 是一種行為型設計模式&#xff0c;它讓多個對象都有機會處理請求&#xff0c;從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈&#xff0c;沿著這條…

1、做中學 | 一年級上期 Golang簡介和安裝環境

一、什么是golang Golang&#xff0c;通常簡稱 Go&#xff0c;是由 Google 公司的 Robert Griesemer、Rob Pike 和 Ken Thompson 于 2007 年創建的一種開源編程語言&#xff0c;并在 2009 年正式對外公布。 已經有了很多編程語言&#xff0c;為什么還要創建一種新的編程語言&…

Linux--迷宮探秘:從路徑解析到存儲哲學

上一篇博客我們說完了文件系統在硬件層面的意義&#xff0c;今天我們來說說文件系統在軟件層是怎么管理的。 Linux--深入EXT2文件系統&#xff1a;數據是如何被組織、存儲與訪問的&#xff1f;-CSDN博客 &#x1f30c; 引言&#xff1a;文件系統的宇宙觀 "在Linux的宇宙中…

淘寶商品數據實時獲取方案|API 接口開發與安全接入

在電商數據獲取領域&#xff0c;除了官方 API&#xff0c;第三方數據 API 接入也是高效獲取淘寶商品數據的重要途徑。第三方數據 API 憑借豐富的功能、靈活的服務&#xff0c;為企業和開發者提供了多樣化的數據解決方案。本文將聚焦第三方數據 API 接入&#xff0c;詳細介紹其優…