Untitled

 avatar
unknown
c_cpp
2 years ago
5.0 kB
3
Indexable
#include<iostream>
#include<vector>
#include<map>
#include<utility>
#include<queue>

using namespace std;

struct Node{
    int ID, cont;
    bool SDN_Node;
    map<int, vector<int>> Children;
    map<int, vector<int>> Table;
};

struct Flow{
    int ID, Src_Node, Dst_Node, Size;
};


class Data{
    public:
        Data();
        void output();
        void input();
        void initialize();
        void BFS();
        void algorithm();
    private:
        int Nodes, SDN_Nodes, Dsts, Links_num, Pairs;
        vector<int> SDN_ary;
        vector<int> Dsts_ary;
        vector<vector<int>> Links_ary;
        vector<Flow> Flow_ary;
        vector<Node> Node_ary;
        void update(bool,int,int,int,int);
        bool getSDN(int);
        bool find(int,int,int);
};

int main(){
    Data a;
    a.initialize();
    a.input();
    a.BFS();
    a.algorithm();
    a.output();

}

Data::Data(){
    cin >> Nodes >> SDN_Nodes >> Dsts >> Links_num >> Pairs;
}

void Data::initialize(){
    Links_ary.resize(Nodes, vector<int>(Nodes, 0));
    SDN_ary.resize(SDN_Nodes, 0);
    Dsts_ary.resize(Dsts, 0);
    Flow_ary.resize(Pairs);
    Node_ary.resize(Nodes);
}

void Data::input(){
    int LinkID, Node1, Node2;

    for (auto it = SDN_ary.begin(); it != SDN_ary.end(); it++){
        cin >> *it;
    }
    for (auto jt = Dsts_ary.begin(); jt != Dsts_ary.end(); jt++){
        cin >> *jt;
    }
    for (int i=0; i < Links_num; i++){
        cin >> LinkID >> Node1 >> Node2;
        Links_ary[Node1][Node2] = 1;
        Links_ary[Node2][Node1] = 1;
    }
    for (auto lt = Flow_ary.begin(); lt != Flow_ary.end(); lt++){
        Flow tmp;
        cin >> tmp.ID >> tmp.Src_Node >> tmp.Dst_Node >> tmp.Size;
        *lt = tmp;
    }
}

void Data::output(){
    // for (auto row:Links_ary){
    //     for (auto val:row){
    //         cout << val << " ";
    //     }
    //     cout << endl;
    // }
    for (auto x:Node_ary){
        cout << x.ID << endl;
        for (auto y:x.Table){
            cout << y.first << " ";
            for (auto z:y.second){
                cout << z ;
                if (x.SDN_Node){
                    double SDN_size = y.second.size();
                    double Proportion = 100.0 / SDN_size;
                    cout << " " << Proportion << "% ";
                }
            }
            cout << endl;            
        }
        
    }
    // cout << endl;
    // for (auto v:Node_ary){
    //     cout << v.ID << endl;
    //     for (auto vv : v.Children){
    //         cout << vv.first << " : " ;
    //         for (auto vvv : vv.second){
    //             cout << vvv << " ";
    //         }
    //         cout << endl;
    //     }
    // }
    
    
}

void Data::algorithm(){
    for (auto DSTS : Dsts_ary){
        for (auto SDN : SDN_ary){
            for (int i = 0; i < Nodes; i++){
                if (Links_ary[SDN][i] == 1 && !find(SDN, DSTS, i) && !(Links_ary[i][DSTS] == 1) ){
                    Node_ary[SDN].Table[DSTS].push_back(i);
                    Node_ary[i].Children[DSTS].push_back(SDN);
                }    
            }
        }
    }
}

bool Data::find(int SDN, int DSTS, int Find_ID){
    auto children_tmp = Node_ary[SDN].Children[DSTS];
    auto table_tmp = Node_ary[SDN].Table[DSTS];
    
    for (auto i = children_tmp.begin(); i != children_tmp.end(); i++){
        if (*i == Find_ID){
            return true;
        }
    }
    for (auto j = table_tmp.begin(); j != table_tmp.end(); j++){
        if (*j == Find_ID){
            return true;
        }
    }
    if (table_tmp.size() > 5){
        return true;
    }
    
    return false;
}

void Data::BFS(){
    for (auto current : Dsts_ary){
        queue<int> q;

        bool visited[Nodes] = {false};
        
        visited[current] = true;
        q.push(current);
        update(true, current, current, current, 0);

        while (!q.empty()){
            int now_node = q.front();
            q.pop();

            for (int i = 0; i < Nodes; i++){
                int link = Links_ary[now_node][i];
                if ( link != 0 && !(visited[i]) ){
                    q.push(i);
                    visited[i] = true;
                    int Cont = Node_ary[now_node].cont;
                    update( true, i, current, now_node, (Cont+1) );
                }
            }
            
        }

    }
}

void Data::update(bool state,int ID, int dis_ID, int par_ID, int cont){
    if (state){
        Node_ary[ID].ID = ID;
        Node_ary[ID].SDN_Node = getSDN(ID);
        Node_ary[ID].cont = cont;
        Node_ary[ID].Table[dis_ID].push_back(par_ID);
        Node_ary[par_ID].Children[dis_ID].push_back(ID);
    }
}

bool Data::getSDN(int ID){
    for (auto &it : SDN_ary){
        if (it == ID){
            return true;
        }
    }
    return false;
}