wenbao与拓扑排序
@ dfs
@ 小数据map存图
1 int mark[maxn], map[maxn][maxn], aim[maxn], cot; 2 bool dfs(int x){ 3 mark[x] = -1; 4 for(int i = 1; i <= n; i++){ 5 if(map[x][i]){ 6 if(mark[i] < 0) return false; 7 if(!mark[i] && !dfs(i)) return false; 8 } 9 } 10 mark[x] = 1; 11 aim[cot--] = x; 12 return true; 13 } 14 int topo(){ 15 cot = n; 16 memset(mark, 0, sizeof(mark)); 17 for(int i = 1; i <= n; i++){ 18 if(!mark[i]){ 19 if(!dfs(i)) return false; 20 } 21 } 22 return true; 23 }
@ 大数据邻接表
1 int mark[maxn], aim[maxn], cot; 2 vector<int> T[maxn]; 3 // 注意如果有多组输入时要清空vector 4 // for(int i = 1; i <= n; i++){ 5 // T[i].clear(); 6 // } 7 bool dfs(int x){ 8 mark[x] = -1; 9 for(int i = 0; i < T[x].size(); i++){ 10 if(mark[T[x][i]] < 0) return false; 11 if(!mark[T[x][i]] && !dfs(T[x][i])) return false; 12 } 13 mark[x] = 1; 14 aim[cot--] = x; 15 return true; 16 } 17 int topo(){ 18 cot = n; 19 memset(mark, 0, sizeof(mark)); 20 for(int i = 1; i <= n; i++){ 21 if(!mark[i]){ 22 if(!dfs(i)) return false; 23 } 24 } 25 return true; 26 }
@ while
@ 小数据map
1 const int maxn = 1e5+10; 2 vector<int> T[maxn]; 3 int n, m, map[maxn][maxn], num[maxn]; 4 void topo(){ 5 int t = 0; 6 while(t != n){ 7 for(int i = 1; i <= n; i++) if(num[i] == 0){ 8 for(int j = 1; j <= n; j++) if(map[i][j]){ 9 num[j] --; 10 } 11 vis[i] --; 12 t++; 13 } 14 } 15 }
@ 大数据邻接表
1 const int maxn = 1e5+10; 2 vector<int> T[maxn]; 3 int n, m, vis[maxn], num[maxn], sum = 0; 4 void topo(){ 5 int t = 0; 6 while(t != n){ 7 for(int i = 1; i <= n; i++) if(vis[i] == 0){ 8 for(int j = 0; j < T[i].size(); j++) { 9 num[T[i][j]] += num[i]%mod; 10 num[T[i][j]] %=mod; 11 vis[T[i][j]] --; 12 } 13 vis[i] --; 14 sum += num[i]%mod, sum %=mod; 15 t++; 16 } 17 } 18 }
http://acm.split.hdu.edu.cn/showproblem.php?pid=1285
1 #include <iostream> 2 #include <cstdio> 3 #include <string.h> 4 using namespace std; 5 const int maxn = 502; 6 int map[maxn][maxn], v[maxn], c[maxn]; 7 int n, m; 8 void toposort(){ 9 int t = 0; 10 while(t<n){ 11 for(int i = 1; i <= n; i++){ 12 if(v[i]==0){ 13 v[i]--; 14 c[t] = i, t++; 15 for(int j = 1; j <= n; j++){ 16 if(map[i][j]) v[j]--; 17 } 18 break; 19 } 20 } 21 } 22 } 23 int main(){ 24 while(scanf("%d %d", &n, &m) ==2){ 25 int a, b; 26 memset(map, 0, sizeof(map)); 27 memset(v, 0, sizeof(v)); 28 for(int i = 0; i < m; i++){ 29 scanf("%d %d", &a, &b); 30 if(map[a][b] == 0){ 31 map[a][b] = 1; 32 v[b]++; 33 } 34 } 35 toposort(); 36 for(int i = 0; i < n; i++){ 37 if(i != n-1) 38 printf("%d ", c[i]); 39 else 40 printf("%d\n", c[i]); 41 } 42 } 43 return 0; 44 }
http://codeforces.com/contest/510/problem/C
输入单词判断是否可以找到一个符合输入顺序的排序
样例:
输入:
3
rivest
shamir
adleman
输出:
bcdefghijklmnopqrsatuvwxyz
老刘的模板确实强
1 #include <iostream> 2 #include <string.h> 3 #include <string> 4 using namespace std; 5 const int maxn = 555; 6 string str1, str2, str3; 7 char a[] = {"abcdefghijklmnopqrstuvwxyz"}; 8 int mark[maxn], map[maxn][maxn]={0}, v[maxn]; 9 10 bool dfs(int u){ 11 //cout<<"&&&&&&&&&&&&&&"<<endl; 12 mark[a[u]] = -1; 13 for(int i = 25; i >= 0; i--) 14 if(map[a[u]][a[i]]){ 15 if(mark[a[i]] < 0) return false; 16 else if(!mark[a[i]] && !dfs(i)) return false; 17 } 18 //cout<<a[u]<<"**************"<<endl; 19 mark[a[u]] = 1; str3 += a[u]; 20 //cout<<str3<<endl; 21 return true; 22 } 23 24 bool toposort(){ 25 //cout<<"**************"<<endl; 26 memset(mark, 0, sizeof(mark)); 27 for(int i = 25; i >= 0; i--){ 28 if(!mark[a[i]]){ 29 if(!dfs(i)) return false; 30 } 31 } 32 return true; 33 } 34 35 int main(){ 36 std::ios::sync_with_stdio(false); 37 int n, flag = 1; 38 cin>>n; 39 cin>>str1; 40 for(int i = 1; i < n; i++){ 41 cin>>str2; 42 int num = 0; 43 for(int i = 0; str1[i]; i++){ 44 if(!str2[i]) break; 45 else if(str1[i] != str2[i]){ 46 map[str1[i]][str2[i]] = 1; 47 //map[str2[i]][str1[i]] = 1; 48 v[str1[i]] = 1; 49 v[str2[i]] = 1; 50 //cout<<str1[i] <<" **"<<str2[i]<<endl; 51 break; 52 } 53 else num++; 54 } 55 //cout<<m<<endl; 56 if(num==str2.length()&&str1.length()>str2.length()) flag = 0; 57 str1 = str2; 58 } 59 //cout<<m<<endl; 60 if(flag&&toposort()){ 61 for(int i = 25; i >= 0; i--) 62 cout<<str3[i]; 63 } 64 else{ 65 cout<<"Impossible"<<endl; 66 } 67 return 0; 68 }
开始a---z的字母预处理出了错,調了半天的bug。。。。。。。。。。。。不想说话;;;;
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <string.h> 5 using namespace std; 6 const int maxn = 555; 7 int map[maxn][maxn] = {0}, v[maxn] = {0}; 8 string str3; 9 char a[]={"abcdefghijklmnopqrstuvwxyz"}; 10 bool toposort(){ 11 for(int m = 0; m < 26; m++){ 12 int flag = 0; 13 for(int i = 0; i < 26; i++){ 14 if(v[a[i]]==0){ 15 //cout<<a[i]<<"***"<<endl; 16 flag = 1; 17 v[a[i]]--; 18 str3 += a[i]; 19 for(int j = 0; j < 26; j++){ 20 //cout<<"&&&&"<<endl; 21 //cout<<a[j]<< "**"<<map[a[i]][a[j]]<<"_____"<<endl; 22 if(map[a[i]][a[j]]) { 23 v[a[j]] --; 24 //cout<<a[j]<<"#################"<<endl; 25 } 26 } 27 break; 28 } 29 } 30 if(flag == 0) return false; 31 } 32 return true; 33 } 34 int main(){ 35 string str1, str2; 36 int n, flag = 1; 37 cin>>n; 38 cin>>str1; 39 for(int j = 1; j< n; j++){ 40 cin>>str2; 41 int num = 0; 42 for(int i = 0; str1[i]; i++){ 43 if(!str2[i]) break; 44 else if(str2[i] != str1[i]){ 45 //cout<<str1[i]<<"*********"<<str2[i]<<endl; 46 if(map[str1[i]][str2[i]] == 0){ 47 map[str1[i]][str2[i]] = 1; 48 v[str2[i]]++; 49 //cout<<str1[i]<<str2[i]<<map[str1[i]][str2[i]]<<"***888"<<endl; 50 //cout<<str2[i]<<"%%%"<<endl; 51 //cout<<v[str2[i]]<<"&&&&&&&&"<<endl; 52 } 53 break; 54 } 55 else num++; 56 } 57 if(num == str2.size() && str1.size() > str2.size()) flag = 0; 58 str1 = str2; 59 } 60 if(flag && toposort()){ 61 cout<<str3<<endl; 62 } 63 else{ 64 cout<<"Impossible"<<endl; 65 } 66 return 0; 67 }
http://hihocoder.com/problemset/problem/1174
当数据量大的时候,最好的办法当然是邻接表(二维数组存不下),那么重点来了,是用while呢还是dfs呢?最好是用dfs。。。。啦啦啦啦啦啦啦~~~~~
1 #include <string.h> 2 #include <iostream> 3 #include <vector> 4 using namespace std; 5 const int maxn = 1e5+10; 6 int t, n, m, a, b; 7 int mark[maxn]; 8 vector<int> T[maxn]; 9 int dfs(int x){ 10 mark[x] = -1; 11 for(int i = 0; i < T[x].size(); i++){ 12 if(mark[T[x][i]] < 0) return false; 13 if(!mark[T[x][i]] && !dfs(T[x][i])) return false; 14 } 15 mark[x] = 1; 16 return true; 17 } 18 int topo(){ 19 memset(mark, 0, sizeof(mark)); 20 for(int i = 1; i <= n; i++){ 21 if(!mark[i]) { 22 if(!dfs(i)) return false; 23 } 24 } 25 return true; 26 } 27 int main(){ 28 cin>>t; 29 while(t--){ 30 cin>>n>>m; 31 for(int i = 1; i <= n; i++){ 32 T[i].clear(); 33 } 34 for(int i = 0; i < m; i++) { 35 cin >> a >> b; 36 T[a].push_back(b); 37 } 38 cout<<(topo() ? "Correct" : "Wrong")<<endl; 39 } 40 return 0; 41 }
http://hihocoder.com/problemset/problem/1175
1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 using namespace std; 5 const int maxn = 1e5+10; 6 const int mod = 142857; 7 vector<int> T[maxn]; 8 int n, m, k, a, vis[maxn], num[maxn], sum = 0, x, y; 9 void topo(){ 10 int t = 0; 11 while(t != n){ 12 for(int i = 1; i <= n; i++) if(vis[i] == 0){ 13 for(int j = 0; j < T[i].size(); j++) { 14 num[T[i][j]] += num[i]%mod; 15 num[T[i][j]] %=mod; 16 vis[T[i][j]] --; 17 } 18 vis[i] --; 19 sum += num[i]%mod, sum %=mod; 20 t++; 21 } 22 } 23 } 24 int main(){ 25 scanf("%d %d %d", &n, &m, &k); 26 for(int i = 0; i < k; i++) {scanf("%d", &a); num[a] = 1;} 27 for(int i = 0; i < m; i++){ 28 scanf("%d %d", &x, &y); 29 T[x].push_back(y); 30 vis[y]++; 31 } 32 topo(); 33 printf("%d\n", sum%mod); 34 return 0; 35 }
只有不断学习才能进步!