Description
Input
Output
Sample Input
3 1 2 abc 2 3 ad 1 3 b 3 1 de 0 0 1 3 2 1 3 2 0 0 2 1 2 z 0 0 1 2 2 1 0 0 0
Sample Output
ab d - z -
Source
传递闭包,不过在TOJ超时了。应该有种更加牛X的做法。
1 #include <stdio.h> 2 #include <string.h> 3 #define MAXN 220 4 5 int n; 6 int f[MAXN][MAXN][26]; 7 8 void floyd(){ 9 for(int k=1; k<=n; k++){ 10 for(int i=1; i<=n; i++){ 11 for(int j=1; j<=n; j++){ 12 for(int c=0; c<26; c++){ 13 if( f[i][k][c] && f[k][j][c]) 14 f[i][j][c]=1; 15 } 16 } 17 } 18 } 19 } 20 int main() 21 { 22 while( scanf("%d" ,&n)!=EOF && n){ 23 memset(f,0,sizeof(f)); 24 int u,v; 25 char ch[30]; 26 while( scanf("%d %d",&u ,&v) ){ 27 if(u==0 && v==0)break; 28 scanf("%s",ch); 29 for(int i=0; ch[i]!='\0'; i++){ 30 f[u][v][ch[i]-'a']=1; 31 } 32 } 33 floyd(); 34 while( scanf("%d %d",&u ,&v) ){ 35 if(u==0 && v==0)break; 36 int flag=0; 37 for(int i=0; i<26; i++){ 38 if( f[u][v][i] ){ 39 printf("%c",i+'a'); 40 flag=1; 41 } 42 } 43 if(!flag){ 44 puts("-"); 45 }else{ 46 puts(""); 47 } 48 } 49 printf("\n"); 50 } 51 return 0; 52 }
大牛的解法,有状态压缩的思想。
f[u][v]:存放是是二进制的状态。
假如u-v之间有a,g,m。那么可以写成 f[u][v]=1000001000001。
它是由以下二进制数通过 |运算得到的。
0000000000001
0000001000000
1000000000000
传递闭包的时候,只要跟当前要取得的位进行&运算就可以了。如果返回是1表示u-v之间的路有当前位所对应的公司参与建造。
1 #include <stdio.h> 2 #include <string.h> 3 #define MAXN 220 4 5 int n; 6 int f[MAXN][MAXN]; 7 8 void floyd(){ 9 for(int k=1; k<=n; k++){ 10 for(int i=1; i<=n; i++){ 11 for(int j=1; j<=n; j++){ 12 f[i][j]=f[i][j]|(f[i][k]&f[k][j]); 13 } 14 } 15 } 16 } 17 18 int main() 19 { 20 while( scanf("%d",&n)!=EOF && n ){ 21 int u,v; 22 char ch[30]; 23 memset(f ,0 ,sizeof(f)); 24 while( scanf("%d %d" ,&u ,&v)!=EOF ){ 25 if(u==0 && v==0)break; 26 scanf("%s",ch); 27 for(int i=0; ch[i]!='\0'; i++){ 28 f[u][v]=f[u][v]|(1<<(ch[i]-'a')); 29 } 30 } 31 floyd(); 32 while( scanf("%d %d" ,&u ,&v)!=EOF ){ 33 if(u==0 && v==0)break; 34 int flag=0; 35 for(int i=0; i<26; i++){ 36 if(f[u][v]&(1<<i)){ 37 flag=1; 38 printf("%c",i+'a'); 39 } 40 } 41 if(!flag) 42 printf("-"); 43 puts(""); 44 } 45 puts(""); 46 } 47 return 0; 48 }