题意:给你n个数,每个数有20个数字,每两个数字之间如果相等的数字数量为17个(一定是17),就能从一个数字到达另一个数字,给你两个数字编号,求从第一个数字编号到第二个数字编号之间最少需要走几次;
解题思路:建个图,然后最短路模板;
代码
#include<iostream> #include<algorithm> #include<cstring> const int inf=0x3f3f3f; using namespace std; int a[255][10]; int dist[255]; int visit[255]; int main() { int Map[255][255]; int n; int startx; int starty; int t; int sum; int temp; char s[25]; int minn; cin>>t; while(t--) { temp=inf; memset(a,0,sizeof(a)); sum=0; memset(Map,inf,sizeof(Map)); memset(dist,inf,sizeof(dist)); cin>>n>>startx>>starty; for(int i=1;i<=n;i++) { cin>>s; for(int j=0;j<=19;j++) { a[i][s[j]-'0']++; } } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j) Map[i][j]=0; else Map[i][j]=inf; } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { sum=0; for(int k=0;k<=9;k++) { sum+=min(a[i][k],a[j][k]); } if(sum==17) { Map[i][j]=1;Map[j][i]=1; } } } for(int i=1;i<=n;i++) dist[i]=Map[startx][i]; memset(visit,0,sizeof(visit)); visit[startx]=1; for(int i=1;i<=n-1;i++) { minn=inf; for(int j=1;j<=n;j++) { if(visit[j]==0&&dist[j]<minn) { temp=j;minn=dist[j]; } } if(temp==inf) break; visit[temp]=1; for(int k=1;k<=n;k++) { if(Map[temp][k]<inf) { if(dist[k]>dist[temp]+Map[temp][k]) dist[k]=dist[temp]+Map[temp][k]; } } } if(dist[starty]==inf) cout<<"-1 "; else cout<<dist[starty]<<endl; } return 0; }