UVA1423Guess (dfs,bfs拓撲排序)
阿新 • • 發佈:2018-12-12
題目連結:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36239
題意:給定S( i , j ) , ( i <= j) 的矩陣表示一個數字序列第i個到第j個元素的連續和的符號,‘+’,‘-’,‘0’,求序列的一種可能值。
思路:矩陣中的每個元素都可以看作是序列字首和之差的結果,若設sum(i)為前i個元素的字首和,則S( i, j )表示sum(j)- sum(i)的結果的符號,可以從確定關係的兩個字首和間連一條有向邊,從小的指向大的(反之亦可),然後進行拓撲排序得到sum(i)的一種大小關係。最後對sum(i)依次賦值,即可得到序列。
敲了兩種版本的拓撲排序,dfs 和 bfs兩種版本
程式碼:
dfs版
#include<bits/stdc++.h> using namespace std; int G[15][15], vis[15], rec[15][15], ans[15], Ans[15]; int len, n; void dfs(int u){ vis[u] = 1; for(int i = 0; i <= n; i++){ if(!vis[i] && G[u][i]) dfs(i); } ans[len--] = u; //記錄路徑,從後往前記錄 } int main(){ int t; scanf("%d", &t); while(t--){ scanf("%d", &n); len = n; memset(G, 0, sizeof(G)); memset(vis, 0, sizeof(vis)); memset(rec, 0, sizeof(rec)); char a; getchar(); for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++){ scanf("%c", &a); if(a == '+') G[i-1][j] = 1; else if(a == '-') G[j][i-1] = 1; else if(a == '0') rec[i-1][j] = rec[j][i-1] = G[i-1][j] = 1; } } for(int i = 0; i <= n; i++) if(!vis[i]) dfs(i); Ans[ans[0]] = 0; for(int i = 1; i <= n; i++){ // 對找到的字首和序列賦值 if(rec[ans[i]][ans[i-1]]) Ans[ans[i]] = Ans[ans[i-1]]; else Ans[ans[i]] = Ans[ans[i-1]] + 1; } for(int i = 1; i <= n; i++){ printf("%d%c", Ans[i]-Ans[i-1], i == n?'\n':' '); } } return 0; }
bfs版
#include<bits/stdc++.h> using namespace std; int G[15][15], rec[15], cnt, n, ans[15]; // rec[i]陣列記錄可能比第i個元素小的序列元素的數量 void bfs(){ queue<int> q; while(!q.empty()) q.pop(); for(int i = 0; i <= n; i++) if(rec[i] == 0) q.push(i); while(!q.empty()){ int sz = q.size(); for(int i = 0; i < sz; i++){ int u = q.front(); q.pop(); ans[u] = cnt; // 對找到的字首和序列賦值 for(int v = 0; v <= n; v++){ if(G[u][v]){ rec[v]--; if(rec[v] == 0) q.push(v); } } } cnt++; } } int main(){ int t; scanf("%d", &t); while(t--){ cnt = 0; char tmp; scanf("%d", &n); memset(G, 0, sizeof(G)); memset(rec, 0, sizeof(rec)); getchar(); for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++){ scanf("%c", &tmp); if(tmp == '+') G[i-1][j] = 1, rec[j]++; else if(tmp == '-') G[j][i-1] = 1, rec[i-1]++; } } bfs(); for(int i = 1; i <= n; i++){ printf("%d%c", ans[i]-ans[i-1], i == n ? '\n' : ' '); } } return 0; }