矩阵与图论系列 题解

1.AT_dp_r Walk

题意

一个有向图有 n n n 个节点,编号 1 1 1 n n n

给出一个二维数组 A 1... n , 1... n A_{1...n,1...n} A1...n,1...n,若 A i , j = 1 A_{i,j}=1 Ai,j=1 说明节点 i i i 到节点 j j j 有一条有向边;

A i , j = 0 A_{i,j}=0 Ai,j=0 则说明节点 i i i 到节点 j j j 没有边。

求长度为 k k k 的路径的方案数。答案模 1 0 9 + 7 10^9+7 109+7

思路

走动一次路径加 1 1 1,一个点对所有点遍历一遍。

直接对矩阵 A A A 快速 k k k 次幂,求 ∑ d a t a ( A ) \sum data(A) data(A) 就好了。

代码

#include
using namespace std;
#define ll long long
const ll N=111,mod=1e9+7;
ll n,k,ans;
struct matrix
{
	ll row,col;//行和列
	ll data[N][N];
	matrix(ll r,ll c,ll isI)
	{
		row=r;
		col=c;
		memset(data,0,sizeof(data));
		if(isI)
		{
			for(int i=1;i<=row;i++)
			data[i][i]=1;
		}
	}
};
matrix operator * (const matrix &a,const matrix &b)
{
	matrix c(a.row,b.col,0);
	for(int i=1;i<=a.row;i++)
	for(int j=1;j<=b.col;j++)
	for(int k=1;k<=a.col;k++)
	c.data[i][j]=(c.data[i][j]+a.data[i][k]*b.data[k][j]%mod+mod)%mod;
	return c;
}
matrix qpow_matrix(matrix a,ll k)
{
	matrix res(a.row,a.col,1);
	while(k)
	{
		if(k&1)res=res*a;
		a=a*a;
		k>>=1;
	}
	return res;
}
int main()
{
	scanf("%lld%lld",&n,&k);
	matrix A(n,n,0);
	matrix ANS(n,n,0);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	scanf("%lld",&A.data[i][j]);
	ANS=qpow_matrix(A,k);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	ans=(ans+ANS.data[i][j])%mod;
	printf("%lld",ans);
	return 0;
}

2.SMOJ k边最短路/洛谷 P2886 USACO07NOV Cow Relays G

题意

给定一张 m m m 条边的无向连通图,求从 s s s t t t 经过 n n n 条边的最短路长度。

1 ≤ n ≤ 1 0 6 1\le n\le 10^6 1n106 2 ≤ m ≤ 100 2\le m\le 100 2m100 1 ≤ u , v ≤ 1000 1\le u,v\le 1000 1u,v1000 1 ≤ w ≤ 1000 1\le w\le 1000 1w1000

思路

改造一下矩阵运算,变成取和最小值即可(变相floyd)。

用矩阵,自觉离散化了。

代码

#include
using namespace std;
#define ll long long
const ll N=102,inf=0x3f3f3f3f;
map<ll,ll>mp;
ll tot;
struct matrix
{
	ll row,col;//行和列
	ll data[N][N];
};
matrix operator * (const matrix &a,const matrix &b)
{
	matrix c;
	memset(c.data,inf,sizeof(c.data));
	for(int i=1;i<=tot;i++)
	for(int j=1;j<=tot;j++)
	for(int k=1;k<=tot;k++)
	c.data[i][j]=min(c.data[i][j],a.data[i][k]+b.data[k][j]);
	return c;
}
matrix qpow_matrix(matrix a,ll k)
{
	matrix res;
	res=a;
	k--;
	while(k)
	{
		if(k&1)res=res*a;
		a=a*a;
		k>>=1;
	}
	return res;
}
ll n,m,s,t;
int main()
{
	scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
	matrix A;
	memset(A.data,inf,sizeof(A.data));
	for(int i=1;i<=m;i++)
	{
		ll w,u,v;
		scanf("%lld%lld%lld",&w,&u,&v);
		if(!mp[u])mp[u]=++tot;
		if(!mp[v])mp[v]=++tot;
		A.data[mp[u]][mp[v]]=A.data[mp[v]][mp[u]]=w;
	}
	A=qpow_matrix(A,n);
	printf("%lld",A.data[mp[s]][mp[t]]);
	return 0;
}

你可能感兴趣的:(矩阵,图论,算法)