uvaLA4255 Guess BFS+拓扑排序
算法指南白书
思路:“连续和转化成前缀和之差”
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <cstring> 10 #include <math.h> 11 #include <stdlib.h> 12 #include <time.h> 13 using namespace std; 14 const int maxn=50; 15 int T,n; 16 int fa[15]; 17 char str[60][60],s[60]; 18 int G[15][15]; 19 int c[15]; 20 vector<int>topo; 21 22 int findset(int x){//并查集求祖先 23 return fa[x]!=x?fa[x]=findset(fa[x]):x; 24 } 25 bool dfs(int u){//拓扑排序 26 c[u]=-1; 27 for(int i=0;i<=n;i++){ 28 if(G[u][i]){ 29 if(c[i]<0) 30 return false; 31 if(c[i]==0) 32 dfs(i); 33 } 34 } 35 c[u]=1; 36 topo.push_back(u); 37 return true; 38 } 39 bool toposort(){ 40 topo.clear(); 41 memset(c,0,sizeof(c)); 42 for(int i=0;i<=n;i++){ 43 if(!c[i]){ 44 if(!dfs(i)) 45 return false; 46 } 47 } 48 reverse(topo.begin(),topo.end()); 49 return true; 50 } 51 int main(){ 52 scanf("%d",&T); 53 while(T--){ 54 scanf("%d",&n); 55 getchar(); 56 scanf("%s",s); 57 int index=0; 58 for(int i=1;i<=n;i++) fa[i]=i; 59 for(int i=1;i<=n;i++){ 60 for(int j=i;j<=n;j++){ 61 str[i][j]=s[index++]; 62 if(str[i][j]=='0') 63 fa[j]=i-1;//i-1和j同祖先 64 } 65 } 66 memset(G,0,sizeof(G)); 67 for(int i=1;i<=n;i++){//sum[i]<sum[j],i到j连一条边 68 for(int j=i;j<=n;j++){ 69 if(str[i][j]=='-') 70 G[findset(j)][findset(i-1)]=1; 71 if(str[i][j]=='+') 72 G[findset(i-1)][findset(j)]=1; 73 } 74 } 75 toposort(); 76 int sum[15]; 77 memset(sum,0,sizeof(sum)); 78 int cur=0; 79 for(int i=0;i<=n;i++){//0到。。。赋值 80 sum[topo[i]]=cur++; 81 } 82 for(int i=1;i<=n;i++){ 83 sum[i]=sum[findset(i)]; 84 if(i>1) 85 printf(" "); 86 printf("%d",sum[i]-sum[i-1]); 87 } 88 printf("\n"); 89 } 90 return 0; 91 }