变色DNA

r囧r小猫 2022-06-11 04:06 284阅读 0赞

有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1,2…N-1。研究发现这只狼的基因中存在一个变色矩阵,记为colormap,如果colormap i i j j=’Y’则这只狼可以在某一个夜晚从颜色i变成颜色j(一晚不可以变色多次),如果colormap i i j j=‘N’则不能在一个晚上从i变成j色。进一步研究发现,这只狼每次变色并不是随机变的,它有一定策略,在每个夜晚,如果它没法改变它的颜色,那么它就不变色,如果存在可改变的颜色,那它变为标号尽可能小的颜色(可以变色时它一定变色,哪怕变完后颜色标号比现在的大)。现在这只狼是颜色0,你想让其变为颜色N-1,你有一项技术可以改变狼的一些基因,具体说你可以花费1的代价,将狼的变色矩阵中的某一个colormap i i j j=’Y’改变成colormap i i j j=’N’。问至少花费多少总代价改变狼的基因,让狼按它的变色策略可以从颜色0经过若干天的变色变成颜色N-1。如果一定不能变成N-1,则输出-1.

Input

多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5
每组测试数据有相同的结构构成:
每组数据第一行一个整数N,2<=N<=50。
之后有N行,每行N个字符,表示狼的变色矩阵,矩阵中只有‘Y’与‘N’两种字符,第i行第j列的字符就是colormap i i j j。

Output

每组数据一行输出,即最小代价,无解时输出-1。

Sample Input

  1. 3
  2. 3
  3. NYN
  4. YNY
  5. NNN
  6. 8
  7. NNNNNNNY
  8. NNNNYYYY
  9. YNNNNYYN
  10. NNNNNYYY
  11. YYYNNNNN
  12. YNYNYNYN
  13. NYNYNYNY
  14. YYYYYYYN
  15. 6
  16. NYYYYN
  17. YNYYYN
  18. YYNYYN
  19. YYYNYN
  20. YYYYNN
  21. YYYYYN

Sample Output

  1. 1
  2. 0
  3. -1 #include<stdio.h>
  4. #include<string.h>
  5. #include<queue>
  6. using namespace std;
  7. struct node
  8. {
  9. int from;
  10. int to;
  11. int w;
  12. int next;
  13. }e[3000];
  14. int cont;
  15. int n;
  16. int vis[51];
  17. int dis[51];
  18. int head[51];
  19. char a[51][51];
  20. void add(int from,int to,int w)
  21. {
  22. e[cont].to=to;
  23. e[cont].w=w;
  24. e[cont].next=head[from];
  25. head[from]=cont++;
  26. }
  27. void SPFA()
  28. {
  29. memset(vis,0,sizeof(vis));
  30. for(int i=0;i<n;i++)dis[i]=0x3f3f3f3f;
  31. dis[0]=0;
  32. vis[0]=1;
  33. queue<int >s;
  34. s.push(0);
  35. while(!s.empty())
  36. {
  37. int u=s.front();
  38. vis[u]=0;
  39. s.pop();
  40. for(int i=head[u];i!=-1;i=e[i].next)
  41. {
  42. int v=e[i].to;
  43. int w=e[i].w;
  44. if(dis[v]>dis[u]+w)
  45. {
  46. dis[v]=dis[u]+w;
  47. if(vis[v]==0)
  48. {
  49. vis[v]=1;
  50. s.push(v);
  51. }
  52. }
  53. }
  54. }
  55. if(dis[n-1]==0x3f3f3f3f)printf("-1\n");
  56. else printf("%d\n",dis[n-1]);
  57. }
  58. int main()
  59. {
  60. int t;
  61. scanf("%d",&t);
  62. while(t--)
  63. {
  64. scanf("%d",&n);
  65. for(int i=0;i<n;i++)
  66. {
  67. scanf("%s",a[i]);
  68. }
  69. cont=0;
  70. memset(head,-1,sizeof(head));
  71. for(int i=0;i<n;i++)
  72. {
  73. int w=0;
  74. for(int j=0;j<n;j++)
  75. {
  76. if(a[i][j]=='Y')
  77. {
  78. add(i,j,w);
  79. w++;
  80. }
  81. }
  82. }
  83. SPFA();
  84. }
  85. }
  86. #include<cstdio>
  87. #include<cstring>
  88. using namespace std;
  89. const int inf=0x3f3f3f3f;
  90. int dis[51][51];
  91. char str[51];
  92. int main()
  93. {
  94. int t,n,ans;
  95. scanf("%d",&t);
  96. while(t--)
  97. {
  98. scanf("%d",&n);
  99. memset(dis,inf,sizeof(dis));
  100. for(int i=0; i<n; i++)
  101. {
  102. ans=0;
  103. scanf("%s",str);
  104. for(int j=0; j<n; j++)
  105. {
  106. if(str[j]=='Y')
  107. dis[i][j]=ans++;
  108. }
  109. }
  110. //printf("%d\n",dist[0][0]);
  111. for(int i=0; i<n; i++)
  112. {
  113. for(int j=0; j<n; j++)
  114. {
  115. for(int k=0; k<n; k++)//k作为中间节点可以放在第一层循环,也可以放在第三层循环,但是不能放在第二层循环
  116. {
  117. if(dis[j][i]+dis[i][k]<dis[j][k])
  118. dis[j][k]=dis[j][i]+dis[i][k];
  119. }
  120. }
  121. }
  122. printf("%d\n",dis[0][n-1]==inf?-1:dis[0][n-1]);
  123. }
  124. return 0;
  125. }
  126. #include <iostream>
  127. #include <algorithm>
  128. #include <cstdio>
  129. #include <cmath>
  130. #include <vector>
  131. #include <string>
  132. #include <cstring>
  133. using namespace std;
  134. const int inf = 0x3f3f3f3f;
  135. char val[55][55];
  136. int minn_cnt;
  137. int n,test;
  138. int edge[55][55];
  139. int vist[55], minidis[55];
  140. void dijkstra()
  141. {
  142. int j, k;
  143. for(int i=1;i<=n;i++)
  144. minidis[i]=edge[1][i];
  145. vist[1] = 1;
  146. minidis[1] = 0;
  147. for (j = 1; j <n; j++)
  148. {
  149. int min_value = inf, min_pos=0;
  150. for (k = 1; k <= n; k++)
  151. {
  152. //printf("sdfgs\n");
  153. if (vist[k] == 0 && minidis[k] < min_value)
  154. {
  155. min_value = minidis[k];
  156. min_pos = k;
  157. }
  158. }
  159. vist[min_pos] = 1;
  160. //position = min_pos;
  161. for (k = 1; k <= n; k++)
  162. {
  163. if (vist[k]==0&&edge[min_pos][k] != inf && minidis[min_pos] + edge[min_pos][k] < minidis[k])//新填入的点更新minidis
  164. {
  165. minidis[k]=minidis[min_pos]+edge[min_pos][k];
  166. }
  167. }
  168. }
  169. }
  170. int main()
  171. {
  172. int i, k;
  173. cin >> test;
  174. while (test--)
  175. {
  176. cin >> n;
  177. for(i=1;i<=n;i++)
  178. {
  179. for(k=i;k<=n;k++)
  180. edge[i][k]=edge[k][i]=inf;
  181. }
  182. for (i = 1; i <= n; i++)
  183. {
  184. cin >> val[i] + 1;
  185. minn_cnt = 0;
  186. for (k = 1; k <= n; k++)
  187. {
  188. if (val[i][k] == 'Y')
  189. {
  190. edge[i][k] = minn_cnt;
  191. minn_cnt++;
  192. }
  193. }
  194. }
  195. fill(minidis,minidis+52,inf);
  196. memset(vist, 0, sizeof(vist));
  197. dijkstra();
  198. //printf("FHGFJH");
  199. if (minidis[n]==inf)
  200. cout << -1 << endl;
  201. else
  202. cout << minidis[n] << endl;
  203. }
  204. return 0;
  205. }

发表评论

表情:
评论列表 (有 0 条评论,284人围观)

还没有评论,来说两句吧...

相关阅读

    相关 DNA序列

    > 一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工

    相关 变色DNA

    有一只特别的狼,它在每个夜晚会进行变色,研究发现它可以变成N种颜色之一,将这些颜色标号为0,1,2...N-1。研究发现这只狼的基因中存在一个变色矩阵,记为colormap,如