# 邻接矩阵运算的应用

struct Matrix {
int s[51][51];
Matrix() { memset(s,0,sizeof(s)); }
int *operator [](int x) { return s[x]; }
}M;
Matrix operator *(Matrix a,Matrix b) { // 矩阵乘法
Matrix c;
for(int k=1; k<=n; ++k)
for(int i=1; i<=n; ++i)
if(a[i][k])
for(int j=1; j<=n; ++j)
if(b[k][j])
(c[i][j]+=a[i][k]*b[k][j])%=mo;
return c;
}
Matrix operator ^(Matrix a,int b) { // 矩阵快速幂
Matrix ans;
for(int i=1; i<=n; ++i) ans[i][i]=1;
for(;b;b>>=1,a=a*a) if(b&1) ans=ans*a;
return ans;
}


# 1.[USACO07NOV]牛继电器Cow Relays

https://www.luogu.org/problemnew/show/P2886

$c[i][j]=min(c[i][j],a[i][k]+b[k][j]);$

# 2.[ZJOI2005]沼泽鳄鱼

https://www.luogu.org/problemnew/show/P2579

# 3.[TJOI2017]可乐

https://www.luogu.org/problemnew/show/P3758

# code

## T1

// luogu-judger-enable-o2
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#define rg register int
#define ll long long
#define RG register
#define il inline
using namespace std;

il int gi() {
rg x=0,o=0;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||'9'<ch)) ch=getchar();
if(ch=='-') o=1,ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return o?-x:x;
}

#define SZ 2000001
int cnt,mp[SZ];
#define INF 2147483647
#define Getmin(a,b) (a)=(a)<(b)?(a):(b)
struct Matrix{ll a[201][201];};
Matrix dis,ans;
Matrix mul(Matrix a,Matrix b) {
Matrix c;
for(rg i=1; i<=cnt; ++i)
for(rg j=1; j<=cnt; ++j)
c.a[i][j]=INF;
for(rg k=1; k<=cnt; ++k)
for(rg i=1; i<=cnt; ++i)
for(rg j=1; j<=cnt; ++j)
Getmin(c.a[i][j],a.a[i][k]+b.a[k][j]);
return c;
}
int n,m,s,t;

il void power(rg b) {
for(rg i=1; i<=cnt; ++i) ans.a[i][i]=0;
while(b) {
if(b&1) ans=mul(ans,dis);
dis=mul(dis,dis);
b>>=1;
}
}
int main() {
n=gi(),m=gi(),s=gi(),t=gi();
memset(mp,-1,sizeof(mp));
memset(ans.a,0x3f,sizeof(ans.a));
memset(dis.a,0x3f,sizeof(dis.a));
for(rg u,v,w,i=1; i<=m; ++i)
{
w=gi(),u=gi(),v=gi();
if(mp[u]==-1) mp[u]=++cnt;
if(mp[v]==-1) mp[v]=++cnt;
u=mp[u],v=mp[v];
Getmin(dis.a[u][v],w);
dis.a[v][u]=dis.a[u][v];
}
power(n);
printf("%lld",ans.a[mp[s]][mp[t]]);
return 0;
}


## T2

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#define rg register int
#define ll long long
#define RG register
#define il inline
using namespace std;

il int gi()  {
rg x=0,o=0;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||'9'<ch)) ch=getchar();
if(ch=='-') o=1,ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return o?-x:x;
}

int N,M,S,T,K,FN;

struct Matrix {
int s[51][51];
Matrix() {memset(s,0,sizeof(s));}
int *operator [](int x) {return s[x];}
}dis[13];

#define MOD 10000
Matrix operator *(Matrix a,Matrix b) {
Matrix c;
for(rg k=1; k<=N; ++k)
for(rg i=1; i<=N; ++i)
if(a[i][k])
for(rg j=1; j<=N; ++j)
if(b[k][j])
(c[i][j]+=a[i][k]*b[k][j])%=MOD;
return c;
}
Matrix operator ^(Matrix a,int b) {
Matrix ans;
for(rg i=1; i<=N; ++i) ans[i][i]=1;
for(;b;b>>=1,a=a*a) if(b&1) ans=ans*a;
return ans;
}

int p[5];
int main() {
N=gi(),M=gi(),S=gi()+1,T=gi()+1,K=gi();
// 因为题目给出的是从 0 开始，所以我们要+1 来强制 从1开始
for(rg x,y,i=1; i<=M; ++i) {
x=gi()+1,y=gi()+1;
for(rg j=1; j<=12; ++j)
dis[j][x][y]=dis[j][y][x]=1;
}
FN=gi();
for(rg i=1; i<=FN; ++i) {
p[0]=gi();
for(rg j=1; j<=p[0]; ++j) p[j]=gi();
for(rg j=1; j<=12; ++j)
for(rg pos=j%p[0]+1,k=1; k<=N; ++k)
dis[j][k][p[pos]+1]=0;
}
for(rg i=1; i<=N; ++i) dis[0][i][i]=1;
for(rg i=1; i<=12; ++i) dis[0]=dis[0]*dis[i];
Matrix Ans=dis[0]^(K/12);
for(rg i=1; i<=K%12; ++i) Ans=Ans*dis[i];
printf("%d",Ans.s[S][T]);
return 0;
}


## T3

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>

#define Getmax(a,b) (a)=(a)>(b)?(a):(b)
#define Getmin(a,b) (a)=(a)<(b)?(a):(b)
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define ll long long
#define gc getchar

using namespace std;

int gi() {
int x=0,o=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||'9'<ch)) ch=getchar();
if(ch=='-') o=1,ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return o?-x:x;
}

const int mo=2017;
int n,m;

struct Matrix {
int s[51][51];
Matrix() { memset(s,0,sizeof(s)); }
int *operator [](int x) { return s[x]; }
}M;
Matrix operator *(Matrix a,Matrix b) {
Matrix c;
for(int k=1; k<=n; ++k)
for(int i=1; i<=n; ++i)
if(a[i][k])
for(int j=1; j<=n; ++j)
if(b[k][j])
(c[i][j]+=a[i][k]*b[k][j])%=mo;
return c;
}
Matrix operator ^(Matrix a,int b) {
Matrix ans;
for(int i=1; i<=n; ++i) ans[i][i]=1;
for(;b;b>>=1,a=a*a) if(b&1) ans=ans*a;
return ans;
}

int main() {
n=gi()+1,m=gi();
for(int i=1; i<=m; ++i) {
int u=gi(),v=gi();
M[u][v]=M[v][u]=1;
}
for(int i=1; i<=n; ++i) M[i][i]=1;
for(int i=1; i<=n-1; ++i) M[i][n]=1;
int t=gi(),ans=0;
M=M^t;
for(int i=1; i<=n; ++i) (ans+=M[1][i])%=mo;
printf("%d",ans);
return 0;
}

posted @ 2018-06-10 09:28  TPLY  阅读(...)  评论(...编辑  收藏