UVA 196 POJ 1420 (拓扑排序--删边法)

拓扑排序;
刚开始想的直接模拟,但没考虑到要是表达式里给的还没给出的边的话,就没法算呀。
看了吴永辉老师的题解,才明白是要进行拓扑排序,想想也很有道理,在我看来删边法最重要的三个部分:入度,邻接表,队列。
正好,这道题满足这三个条件,入度为零的点即为已知的点,压入队列中,对每个表达式项( i , j ),取出其中的每一项,计算其对应的行号 X 列号 Y ,(i,j)送入(x,y)的邻接表中,并累计(i,j)的入度。
从队列中取出入度为零的点,进行删边操作。同时给对应的边赋值,将过程中入度变为0的点压入队列中,往复直到队列为空。
这样的拓扑排序就构造成功。
code 如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<list>
#include<queue>
#define mm(a,b) memset(a,b,sizeof(a))
#define ACCELERATE (ios::sync_with_stdio(false),cin.tie(0))
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
using namespace std;
int mmp[100][100];

struct point{
    int x;
    int y;
    point(int a,int b):x(a),y(b){}
};

list<point> g[100][100];

int ind[100][100];

int main()
{
    int n;
    scanf("%d",&n);
    while(n--){
        char s[100];
        int a,b;
        scanf("%d%d",&a,&b);
        memset(mmp,0,sizeof(mmp));
        memset(ind,0,sizeof(ind));
        for(int i=1;i<=b;i++){
            for(int j=1;j<=a;j++){
                scanf("%s",s);
                if(s[0]=='='){
                    int ans=0;
                    char alpha[4];
                    char digit[4];
                    int j1=0,j2=0;
                    for(int k=1;s[k];k++){
                        if(isalpha(s[k])) alpha[j1++]=s[k];
                        else if(isdigit(s[k])) digit[j2++]=s[k];
                        else{
                            int col=0,row=0;
                            while((--j1)>=0){
                                int flag=26;
                                col=col*26+alpha[j1]-64;
                            }
                            while((--j2)>=0){
                                int flag=10;
                                row=row*10+digit[j2]-48;
                            }
                            ind[i][j]++;
                            point t(i,j);
                            g[row][col].push_back(t);
                            j1=j2=0;
                        }
                    }
                    int col=0,row=0;
                    while((--j1)>=0){
                        int flag=26;
                        col=col*26+alpha[j1]-64;
                    }
                    while((--j2)>=0){
                        int flag=10;
                        row=row*10+digit[j2]-48;
                    }
                    ind[i][j]++;
                    point t(i,j);
                    g[row][col].push_back(t);
                }else mmp[i][j]=atoi(s);
            }
        }
        queue<point> q;
        for(int i=1;i<=b;i++){
            for(int j=1;j<=a;j++){
                if(ind[i][j]==0){
                    point t(i,j);
                    q.push(t);
                }
            }
        }
        while(!q.empty()){
            point t=q.front();
            q.pop();
            for(list<point>::const_iterator it=g[t.x][t.y].begin();it!=g[t.x][t.y].end();it++){
                mmp[it->x][it->y]+=mmp[t.x][t.y];
                ind[it->x][it->y]--;
                if(ind[it->x][it->y]==0){
                    q.push(point(it->x,it->y));
                }

            }
        }
        for(int i=1;i<=b;i++){
            for(int j=1;j<=a;j++){
                if(j!=1) printf(" ");
                printf("%d",mmp[i][j]);
            }
            puts("");
        }
        for(int i=1;i<=b;i++){
            for(int j=1;j<=a;j++){
                if(!g[i][j].empty())  g[i][j].clear();
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/80680890