您的位置:首页 > 产品设计 > UI/UE

UVA1423Guess (dfs,bfs拓扑排序)

2015-09-24 23:25 501 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: