poj 1420

来源:互联网 发布:jira有内置数据库吗 编辑:程序博客网 时间:2024/06/06 01:03
这道题主要就是拓扑排序,还是用的删边法,由于是表格坐标确定位置,所以先将元素的 二维坐标转换成了一维坐标(看了讨论版,好像测试数据比较水,所以在代码中有点投机取巧)
#include <iostream>#include <string>using namespace std;//据说数据不会很大const int maxn_map = 1000;//总结点个数const int maxn = 100;int mt[maxn][maxn];//表格矩阵short map[maxn_map][maxn_map];//连接关系矩阵bool has[maxn_map];int pre[maxn_map];int queue[maxn_map];int tot;//拓扑排序队尾指针int trans(const string & str){int res = 0;for(int i = 0;i < str.size();i++)res = res *10 +  (str[i] - '0');return res;}void createmap(const string & str,int row,int col)//构造指向 (row,col) pos 的关系 , row col is i and j ,so we need a little change{int pos = col * maxn + (row + 1);//目标结点has[pos] = true;for(int i = 1;i < str.size();)//处理整个表达式{int pos_col = 0,pos_row = 0;//坐标换算后的行列位置(col --)for(;(str[i] != '+') && (i < str.size() );i++)//依次处理各个坐标{if(str[i] >= 'A' && str[i] <= 'Z')pos_col = pos_col * 26 + (str[i] - 'A'  + 1);elsepos_row = pos_row * 10 + (str[i] - '0');}pos_col--;int posfrom = pos_col * maxn + pos_row;//结点位置has[posfrom] = true;map[posfrom][pos] = 1;pre[pos]++;i++;// "+"}}void kahn()//拓扑排序{for(int i = 1;i < maxn_map;i++){if(0==pre[i] && has[i])queue[tot++] = i;}for(int i = 0;i < tot;i++){has[queue[i]] = false;for(int k = 1;k < maxn_map;k++)//删除关联的边,在相应节点上加上 数字{if(1==map[queue[i]][k]){//this has a big problem//mt[(k % (maxn + 1)) - 1][(k - 1) / 100] += mt[(queue[i] % (maxn +1)) - 1][(queue[i] - 1) / 100];int ti = k % maxn - 1;if(ti < 0)ti += 100;int tj = (k - 1)/100;int ri = queue[i] % maxn - 1;if(ri < 0)ri +=100;int rj = (queue[i] - 1)/100;mt[ti][tj] += mt[ri][rj];pre[k]--;if(0==pre[k] && has[k])queue[tot++] = k;}}//for int k}}void init(int col,int row){memset(mt,0,sizeof(mt));memset(map,0,sizeof(map));memset(pre,0,sizeof(pre));memset(queue,-1,sizeof(queue));memset(has,false,sizeof(has));string str;for(int i = 0;i < row;i++){for(int j = 0;j < col;j++){cin>>str;if(str[0] != '=')//输入为数字{mt[i][j] = trans(str);has[j * 100 + i + 1] = true;}else//构造有向图{createmap(str,i,j);mt[i][j] = 0;}}}//for int itot = 0;}int main(){freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);int casenum;cin>>casenum;while(casenum--){int col,row;cin>>col>>row;init(col,row);kahn();for(int i = 0;i < row;i++){for(int j = 0;j < col;j++)cout<<mt[i][j]<<" ";cout<<endl;}}return 0;}


0 0
原创粉丝点击