UVA1423Guess (dfs,bfs拓扑排序)

题目链接: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;
}



猜你喜欢

转载自blog.csdn.net/Mad_boys/article/details/48720439