标签:
3 3 3 3 3 3 3 3 1 1
一个无向图,有三个人,起点任意,但是三个人所在城市的频率差值不大于k 每次三人都必须移动到下一个点或者三人选择此时结束任务
问 对于起始点i j k 有几种结束方案
记忆化搜索 暴力枚举起点状态
/************************************************ ┆ ┏┓ ┏┓ ┆ ┆┏┛┻━━━┛┻┓ ┆ ┆┃ ┃ ┆ ┆┃ ━ ┃ ┆ ┆┃ ┳┛ ┗┳ ┃ ┆ ┆┃ ┃ ┆ ┆┃ ┻ ┃ ┆ ┆┗━┓ ┏━┛ ┆ ┆ ┃ ┃ ┆ ┆ ┃ ┗━━━┓ ┆ ┆ ┃ AC代马 ┣┓┆ ┆ ┃ ┏┛┆ ┆ ┗┓┓┏━┳┓┏┛ ┆ ┆ ┃┫┫ ┃┫┫ ┆ ┆ ┗┻┛ ┗┻┛ ┆ ************************************************ */ #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<iostream> #include<queue> #include<map> #define ll long long using namespace std; ll sum[55][55][55]; int n,m,K,q; bool Map[55][55]; int num[55],d[55]; const ll mod=998244353; bool cheak(int i,int j,int l) { if(num[i]-num[j]>K||num[j]-num[i]>K) return false ; if(num[i]-num[l]>K||num[l]-num[i]>K) return false ; if(num[l]-num[j]>K||num[j]-num[l]>K) return false ; return true ; } int Abs(int i) { if(i<0) i=-i; return i; } ll dfs(int i,int j,int k) { if(sum[i][j][k]>=0) return sum[i][j][k]; ll ans=0; for(int ii=1; ii<=n; ii++) { if(Map[i][ii]) { for(int jj=1; jj<=n; jj++) { if(Map[j][jj]&&Abs(num[ii]-num[jj])<=K) { for(int l=1; l<=n; l++) { if(Map[k][l]&&cheak(ii,jj,l)) { ans=(ans+dfs(ii,jj,l))%mod; } } } } } } sum[i][j][k]=(ans+1)%mod; return (ans+1)%mod; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&n,&m,&K,&q); for(int i=1; i<=n; i++) scanf("%d",&num[i]); memset(sum,-1,sizeof(sum)); memset(Map,false ,sizeof(Map)); memset(d,0,sizeof(d)); for(int i=0; i<m; i++) { int u,v; scanf("%d%d",&u,&v); Map[u][v]=true; d[v]++; } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(Abs(num[i]-num[j])<=K) for(int k=1; k<=n; k++) if(cheak(i,j,k)) sum[i][j][k]=dfs(i,j,k); for(int i=0; i<q; i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); printf("%d\n",sum[a][b][c]); } } return 0; }
标签:
原文地址:http://blog.csdn.net/u013097262/article/details/52138463