zoukankan      html  css  js  c++  java
  • 洛谷 P4159 [SCOI2009]迷路

    windy在有向图中迷路了。 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1。 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。

    根据题意,可以写出转移方程

    \[f_{i,j}=\sum f_{r,j-w[r]} \]

    \(f_{i,j}\)表示第\(j\)时刻在第\(i\)个点时的方案数,\(r\)\(i\)的前驱,\(w[r]\)为距离

    \(T\le 10^9\),所以肯定是不可行的,就要用到矩阵加速

    如果对于上面那个转移方程是无法矩阵加速的

    但是边权只有\(1…9\),我们可以把\(j\)分开表示,也就是把所有距离的情况都表示出来

    那么对于上面的那个转移方程就有两种转移形式

    • 这个距离\(j\)不是真正的距离,那么\(f_{r,j}\)可以从\(f_{r,j-1}\)继承

    • 这个\(j\)是真正的距离,那么\(f_{r,j}\)\(f_{i,j}\)是有贡献的

    代码和拆点一样= =

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,t,d[500][500],s[500][500],b[500][500],p=2009;
    char ch;
    void jzc(int x[500][500],int y[500][500])
    {
    	for (int i=1;i<=n*9;i++)
    		for (int j=1;j<=n*9;j++)
    			for (int k=1;k<=n*9;k++)
    				b[i][j]=(b[i][j]+x[i][k]*y[k][j]%p)%p;
    	for (int i=1;i<=n*9;i++)
    		for (int j=1;j<=n*9;j++)
    			x[i][j]=b[i][j],b[i][j]=0;
    }
    int main()
    {
    	cin>>n>>t;
    	for (int i=1;i<=n;i++)
    	{
    		for (int j=1;j<=8;j++)     //第一个的继承关系
    			d[i+j*n][i+(j-1)*n]=1;
    		for (int j=1;j<=n;j++)
    		{
    			cin>>ch;
    			d[i][j+n*((ch-'0')-1)]=1;   //真正的边
    		}
    	}
    	for (int i=1;i<=n*9;i++)
    		s[i][i]=1;
    	while (t)
    	{
    		if (t&1)jzc(s,d);
    		jzc(d,d);
    		t>>=1;
    	}
    	cout<<s[1][n]<<endl;
    	return 0;
    }
    
  • 相关阅读:
    方法重载
    构造方法:(特殊方法,用来创建对象 没写就会默认有构造方法)
    java:第十二章
    java:第九章
    java:第十四章
    java:第十五章
    java:第十一章
    I/O小结
    java:第八章
    java:第六章
  • 原文地址:https://www.cnblogs.com/sdlang/p/13068083.html
Copyright © 2011-2022 走看看