[YZOJ]P1397-奔跑的骑士-矩阵建模
来源:互联网 发布:笔记本电脑必备软件 编辑:程序博客网 时间:2024/05/24 07:16
链接
题意描述:
给定一张无向图,一个起点一个终点。
定义一条合法路径为不存在任何一条满足A->B->A的关系的子路径。
求从起点到终点长为一个值的路径数。
数据范围:
对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。
对于100%的数据,N ≤ 20,M ≤ 60,t ≤ 2147483647,0 ≤ A,B<=N-1。
解法:
30分做法:用队列维护走过当前长度到达的点,拓展转移可行转移。当长度达到定值的时候,若达到终点,则答案加一。
复杂度:最劣
100分做法:
由于转移次数较多,很自然的想到可以利用矩阵表示转移,用快速幂进行优化。
问题在于,如何用一个矩阵表示一系列转移?
用一个数列表示当前走到每个点的方案数。这些数在一步操作后会发生复杂的转移,累加到其他格子里面去,这正是矩阵所支持的。
若没有合法路径的限制?
最直观的想法是,在矩阵中,一行表示当前点被转移的来源。若存在j->i的路径,则
这样乘上一个矩阵就表示进行了一次全部的转移。
如果加上路径的限制条件呢?
相当于只能“向前走”。可惜,点是不具有方向性的,所以我们把转移对象选择为边。边可以分成两条,分别为u->v和v->u,而按照这个想法,如果存在v->k,则边u->v可以向v->k转移。按照这个想法我们就重新建立了一个合法的矩阵。
#include<cstdio>#include<algorithm>#include<cstring>#define R register#define mod 45989#define ll long longusing namespace std;struct new_node{int a,b;}node[125];int n,m,kk,A,B;int nt;int bs[125];int read(){ R int xx;R char ch; while(ch=getchar(),ch<'0'||ch>'9');xx=ch-'0'; while(ch=getchar(),ch>='0'&&ch<='9')xx=xx*10+ch-'0'; return xx;}struct MAT{ int a[123][123]; inline MAT operator * (const MAT &f)const { R MAT ret; R int i,j,k; for(i=0;i<=nt;++i) for(j=0;j<=nt;++j) { ret.a[i][j]=0; for(k=0;k<=nt;++k) ret.a[i][j]=(ret.a[i][j]+a[i][k]*f.a[k][j])%mod; } return ret; } }v0,v1,ans;void pow(int k){ R MAT base=v1; ans=v0; while(k) { if(k&1)ans=ans*base; base=base*base;k>>=1; }}void build(){ R int i,j,x,y; memset(v0.a,0,sizeof(v0.a)); memset(v1.a,0,sizeof(v1.a)); memset(bs,0,sizeof(bs)); nt=-1; for(i=1;i<=m;++i) { x=read(),y=read(); node[++nt]=(new_node){x,y}; node[++nt]=(new_node){y,x}; } for(i=0;i<=nt;++i) { for(j=0;j<=nt;++j) { if(node[i].a==node[j].b&&i!=(j^1)) v1.a[i][j]=1; } } for(i=0;i<=nt;++i)v0.a[i][i]=1;}void print(){ int sum=0; R int i,e; for(i=0;i<=nt;++i) if(node[i].a==A) bs[i]=1; for(e=0;e<=nt;++e) if(node[e].b==B) { for(i=0;i<=nt;++i) sum=(sum+(ll)bs[i]*ans.a[e][i])%mod; } printf("%d",sum);}int main(){ n=read(),m=read(),kk=read(),A=read(),B=read(); build();pow(kk-1);print(); return 0;}/* void show() { printf("begin:\n"); R int i,j; for(i=0;i<=nt;++i,printf("\n")) for(j=0;j<=nt;++j) printf("%d ",a[i][j]); printf("end\n"); } */
阅读全文
0 0
- [YZOJ]P1397-奔跑的骑士-矩阵建模
- [YZOJ]P2417-[FJWC2016]翻转硬币-最短路建模
- 数学建模--矩阵的引用
- 低秩矩阵的应用--背景建模
- 低秩矩阵的应用--背景建模
- 奔跑的感觉
- 无奈的奔跑者
- 奔跑的动力
- 奔跑的人生
- ACM的奔跑
- 奔跑的小狮子
- 奔跑的九月!
- 迷途奔跑的野猪
- 奔跑的2017
- 奔跑的人生
- 奔跑的力量
- [YZOJ]P3238
- 奔跑
- python钩子脚本
- java如何得到GET和POST请求URL和参数列表(转载)
- LeetCode:1_TwoSum--C++实现
- 【转载】京东资深架构师代码评审歪诗
- Mysql sql语句一些需要注意的坑
- [YZOJ]P1397-奔跑的骑士-矩阵建模
- pc端点击图片放大效果
- ConfigReader(十二)—— ReadGuideClickButtonTaskConfig
- 解决utf-8编码下 echo 弹出javascript alert中文乱码解决方法
- cudamat安装
- 作业1平均数2
- PHP-去掉微信昵称表情
- 金蝶K/3Cloud凭证数据库表
- Android annotation 使用注意事项