P6190 [NOI Online] 题解
题目链接
description
给定一张简单带权有向图以及一个非负整数
solution
考虑dp做法。
考虑如何转移。
一段改变了不超过
-
从起点到路径上某个点,改变不超过
次权值的路径 -
从该点到终点改变不超过 1 次权值的路径
类比floyd枚举中转点即可,由此可知
我们还需要求出
先做一遍 floyd 求出
然后dp,时间复杂度
考虑优化。
因为
所以可以把
那么
于是我们只需矩阵快速幂求出
时间复杂度
code
#include<bits/stdc++.h> //代码应该比较明白了,就不写注释了qwq using namespace std; template<typename T> void read(T &x){ x=0; int sgn=0; char c=getchar(); while(!isdigit(c)) sgn|=(c=='-'),c=getchar(); while(isdigit(c)) x=x*10-'0'+c,c=getchar(); if(sgn) x=-x; } const int N=110,M=2510; int n,m,k; long long w[N][N]; struct Matrix{ int _n,_m; long long _[N][N]; void prin(){ cerr<<endl<<"DEBUG"<<endl; for(int i=1; i<=_n; i++){ for(int j=1; j<=_m; j++){ cerr<<_[i][j]<<' '; } cerr<<endl; } cerr<<endl; } friend Matrix operator*(const Matrix &x,const Matrix &y){ Matrix z; z._n=x._n,z._m=y._m; memset(z._,0x3f,sizeof z._); for(int i=1; i<=z._n; i++) z._[i][i]=0; for(int i=1; i<=z._n; i++){ for(int k=1; k<=x._m; k++){ for(int j=1; j<=z._m; j++){ z._[i][j]=min(z._[i][j],x._[i][k]+y._[k][j]); } } } return z; } }; vector<pair<int,int>> edge; inline Matrix qpow(Matrix a,int b){ Matrix ret; memset(ret._,0x3f,sizeof ret); ret._n=ret._m=a._n; for(int i=1; i<=a._n; i++) ret._[i][i]=0; while(b){ if(b&1) ret=ret*a; a=a*a; b>>=1; } return ret; } int main(){ read(n),read(m),read(k); memset(w,0x3f,sizeof w); for(int i=1; i<=m; i++){ int x,y,z; read(x),read(y),read(z); w[x][y]=z; edge.push_back({x,y}); } for(int i=1; i<=n; i++) w[i][i]=0; Matrix A0; for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ A0._[i][j]=w[i][j]; if(i==j) A0._[i][j]=0; } } A0._n=A0._m=n; for(int k=1; k<=n; k++){ for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ A0._[i][j]=min(A0._[i][k]+A0._[k][j],A0._[i][j]); } } } if(k==0){ //记得特别处理一下k=0的情况 //原因是 f_0!=(f_1)^0 printf("%lld\n",A0._[1][n]); return 0; } Matrix A1=A0; for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ for(auto p:edge){ A1._[i][j]=min(A1._[i][j],A0._[i][p.first]+A0._[p.second][j]-w[p.first][p.second]); } } } auto res=qpow(A1,k); /* res.prin(); A1.prin(); A0.prin(); */ printf("%lld\n",res._[1][n]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!