P2151 [SDOI2009] HH去散步 题解
简要题意:有
因为要满足题目关于边的条件,所以我们考虑点边互换。
将
则从第
先考虑用动态规划思考转移方程:
因为
构造转移矩阵
构造初始矩阵
若
上代码:
#include<bits/stdc++.h> #define ll long long #define PLL pair<ll,ll> using namespace std; const ll M=130,mod=45989; ll n,m,ti,s,t,flag; ll u,v,idx,ans; struct fu { ll from,to; }bian[200]; struct jgt { ll a[M][M]; }A,B; jgt operator * (const jgt t1,const jgt t2) { jgt t={0}; for(ll i=0;i<=idx;i++) for(ll j=0;j<=idx;j++) for(ll k=0;k<=idx;k++) t.a[i][j]=(t.a[i][j]+(t1.a[i][k]*t2.a[k][j])%mod)%mod; return t; } void sc(jgt t1) { printf("输出:\n"); for(ll i=0;i<=idx;i++) { for(ll j=0;j<=idx;j++) printf("%lld ",t1.a[i][j]); printf("\n"); } printf("输出完毕!\n"); } int main() { scanf("%lld %lld %lld %lld %lld",&n,&m,&ti,&s,&t); for(ll i=1;i<=m;i++) { scanf("%lld %lld",&u,&v); bian[idx++]={u,v}; bian[idx++]={v,u}; } idx--,ti--; for(ll i=0;i<=idx;i++) for(ll j=0;j<=idx;j++) if(bian[i].to==bian[j].from&&j!=i&&j!=(i^1)) B.a[i][j]=1; for(ll i=0;i<=idx;i++) { for(ll j=0;j<=idx;j++) if(bian[i].to==bian[j].from&&bian[j].from==s) A.a[i][j]=1; if(bian[i].to==s) { flag=i; break; } } while(ti) { if(ti&1) A=A*B; B=B*B; ti=ti/2; } for(ll j=0;j<=idx;j++) if(bian[j].to==t) ans=(ans+A.a[flag][j])%mod; printf("%lld\n",ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】