wenbao与拓扑排序

Posted wenbao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

 

 

 

只有不断学习才能进步!

 

以上是关于wenbao与拓扑排序的主要内容,如果未能解决你的问题,请参考以下文章

拓扑排序详解与实现

wenbao与bfs

数据结构与算法简记--拓扑排序

wenbao与字符串处理

数据结构大题拓扑排序与逆拓扑排序

wenbao与三分