百度之星 迷失 题解(矩阵快速幂+分层图)
题目链接
题目大意
走的步数是固定的,那么容易想到矩阵快速幂
然后再把每个点分为两个点有附魔的和没附魔的。
然后根据边的属性重新连边,然后在跑矩阵快速幂即可
复杂度\(O(n^3logk)\) 但是hdu现在的机子跑不过去了。。。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=2e2+5,inf=0x3f3f3f3f,mod=998244353;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-7;
int n,m,k;
vector<pii> vec[maxn];
ll ni(ll a,ll b){
ll ans=1,base=a;
while(b){
if(b&1) ans=ans*base%mod;
base=base*base%mod;
b=b>>1;
}
return ans;
}
struct matrix{
ll a[maxn][maxn];
}base,ans;
matrix mul(matrix a,matrix b,int n){
matrix temp;
memset(temp.a,0,sizeof(temp.a)); //一定1要清空
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
temp.a[i][k]+=(a.a[i][j])*(b.a[j][k]);
temp.a[i][k]%=mod;
}
}
}
return temp;
}
void qpow(ll n,ll b){
while(b){
if(b&1){
ans=mul(ans,base,n);
}
base=mul(base,base,n);
b=b>>1;
}
}
int main(){
int _; cin>>_;
while(_--){
cin>>n>>m>>k;
memset(ans.a,0,sizeof(ans.a));
memset(base.a,0,sizeof(base.a));
for(int i=1;i<=n;i++) vec[i].clear();
for(int i=1;i<=2*n;i++) ans.a[i][i]=1;
for(int i=1,u,v,w;i<=m;i++){
cin>>u>>v>>w;
vec[u].push_back({v,w});
vec[v].push_back({u,w});
}
for(int i=1;i<=n;i++){
ll g=ni(1ll*vec[i].size(),mod-2);
for(int j=0;j<vec[i].size();j++){
if(vec[i][j].se==1){
base.a[i][vec[i][j].fi+n]=g;
base.a[i+n][vec[i][j].fi]=g;
}else{
base.a[i][vec[i][j].fi]=g;
base.a[i+n][vec[i][j].fi+n]=g;
}
}
}
qpow(2*n,k);
printf("%lld\n",ans.a[1][2*n]);
}
return 0;
}
不摆烂了,写题