SUFE||数据结构:第八章:图

邻接表:

struct L_Node{//这是图中的一个节点
    int data;
    L_Node *Next;
};
struct E_Node{//这是插入时的边节点,代表插入的i和j直接的边
    int i;
    int j;
}
void add_Edge(vector<L_Node>&Ns,int a,int b){
    for(int i=0;i<Ns.size();i++){
        if(Ns[i].data==a){
            L_Node *tmp=Ns[i].Next;
            Ns[i].Next=new L_Node{b,tmp};
        }
        if(Ns[i].data==b){
            L_Node *tmp=Ns[i].Next;
            Ns[i].Next=new L_Node{a,tmp};
        }
    }
}
vector<L_Node> Create_A_Pic(vector<E_Node>Evec){
    vector<L_Node> N;
    for(auto i=Evec.begin();i!=Evec.end();i++){
        int a=i->i,b=i->j; bool charge1=false,charge2=false;
        for(int i=0;i<N.size();i++){
            if(N[i].data==a){
                charge1=true;
            }
            if(N[i].data==b){
                charge2=true;
            }
        }
        if(charge1==false){
            N.push_back(L_Node{a,nullptr});
        }
        if(charge2==false){
            N.push_back(L_Node{b,nullptr});
        }
        add_Edge(N,a,b);
    }
    return N;
}


void dfs(vector<L_Node>N){
    int visit[1000];
    for(int i=0;i<1000;i++) visit[i]=0;
    stack<L_Node>st;
    st.push(N[0]);
    while(!st.empty()){
        L_Node tmp=st.top();
        st.pop();
        if(visit[tmp.data]==1) continue;
        cout<<tmp.data<<endl;
        visit[tmp.data]=1;
        for(auto i=tmp.Next;i!=nullptr;i=i->Next)
        {
            if(visit[i->data]==0){
                for(int k=0;k<N.size();k++){
                    if(N[k].data==i->data){
                        st.push(N[k]);
                        break;
                    }
                }
            }
        }
    }
}

void bfs(vector<L_Node>N){
    int visit[1000];
    for(int i=0;i<1000;i++) visit[i]=0;
    queue<L_Node>q;
    q.push(N[0]);
    while(!q.empty()){
        L_Node tmp=q.front();
        q.pop();
        if(visit[tmp.data]==1){
            continue;
        }
        cout<<tmp.data<<endl;
        visit[tmp.data]=1;
        for(auto i=tmp.Next;i!=nullptr;i=i->Next){
            if(visit[i->data]==0){
                for(int k=0;k<N.size();k++){
                    if(N[k].data==i->data){
                        q.push(N[k]);
                        break;
                    }
                }
            }
        }
    }
}
void print(vector<L_Node>vec){
    for(int i=0;i<vec.size();i++){
        cout<<vec[i].data<<":";
        for(auto j=vec[i].Next;j!=nullptr;j=j->Next){
            cout<<j->data<<"、";
        }
        cout<<endl;
    }
    cout<<endl<<endl;
}

Prim算法求最小生成树:

#define MAXN 50

struct Node{
    int data;
    vector<Node*>subtree;
};
struct edge{
    int s;
    int e;
    int index;
};
void FloorPrint(Node *root){
    queue<Node*> q;
    q.push(root);
    while(!q.empty()){
        Node*tmp=q.front();
        q.pop();
        cout<<tmp->data<<" ";
        for(int i=0;i<tmp->subtree.size();i++){
            q.push(tmp->subtree[i]);
        }
    }
    cout<<endl;
}
set<int>SetInTree;
vector<edge>TreeEdge;
Node* CreateTree(vector<edge>TreeEdge,int no){
    Node *root=new Node{no,{}};
    for(int i=0;i<TreeEdge.size();i++){
        if(TreeEdge[i].s==no){
            Node*tmp=CreateTree(TreeEdge,TreeEdge[i].e);
            root->subtree.push_back(tmp);
        }
    }
    return root;
}
void Prim(int cost[][MAXN],int n,int sum){
    if(SetInTree.size()==n){
        cout<<sum<<endl;
        return;
    }
    if(SetInTree.empty()){
        int index=9999,x1=-1,y1=-1;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(cost[i][j]<index&&cost[i][j]!=0&&i!=j){
                    x1=i;
                    y1=j;
                    index=cost[i][j];
                }
            }
        }
        cout<<x1+1<<" "<<y1+1<<" "<<index<<endl;
        SetInTree.insert(x1);
        SetInTree.insert(y1);
        TreeEdge.push_back(edge{x1+1,y1+1,index});
        Prim(cost,n,sum+index);

    }else{
        int index=9999,x1=-1,y1=-1;
        for(auto i=SetInTree.begin();i!=SetInTree.end();i++){
            for(int j=0;j<n;j++){
                if(cost[*i][j]<index&&SetInTree.find(j)==SetInTree.end()&&cost[*i][j]!=0){
                    index=cost[*i][j];
                    x1=*i;
                    y1=j;
                }
            }
        }
        cout<<x1+1<<" "<<y1+1<<" "<<index<<endl;
        SetInTree.insert(x1);
        SetInTree.insert(y1);
        TreeEdge.push_back(edge{x1+1,y1+1,index});
        Prim(cost,n,sum+index);
    }
}
/*5
0 2 0 6 0
2 0 3 8 5
0 3 0 0 7
6 8 0 0 9
0 5 7 9 0*/
int main(){
    int Cost[MAXN][MAXN];
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>Cost[i][j];
        }
    }
    Prim(Cost,n,0);
    FloorPrint(CreateTree(TreeEdge,1));
    return 0;
}

Kruskal算法:


#define MAXN 50
struct Node{
    int data;
    vector<Node*>subtree;
};
struct edge{
    int s;
    int e;
    int index;
};
set<set<int>>Closure;
vector<edge>TheSetOfTree;
int vis[50]={0};
Node* CreateTree(vector<edge>TreeEdge,int no){
    Node *root=new Node{no,{}};
    for(int i=0;i<TreeEdge.size();i++){
        if(TreeEdge[i].s==no&&vis[i]==0){
            vis[i]=1;
            Node*tmp=CreateTree(TreeEdge,TreeEdge[i].e);
            root->subtree.push_back(tmp);
        }else if(TreeEdge[i].e==no&&vis[i]==0){
            vis[i]=1;
            Node*tmp=CreateTree(TreeEdge,TreeEdge[i].s);
            root->subtree.push_back(tmp);
        }
    }
    return root;
}
void FloorPrint(Node *root){
    queue<Node*> q;
    q.push(root);
    while(!q.empty()){
        Node*tmp=q.front();
        q.pop();
        cout<<tmp->data<<" ";
        for(int i=0;i<tmp->subtree.size();i++){
            q.push(tmp->subtree[i]);
        }
    }
    cout<<endl;
}
void quickSort(vector<edge>&edgeSet,int i,int j){
    if(j<=i) return;
    edge tmp = edgeSet[i];
    int b=i,e=j;
    while(b<e){
        for(;b<e&&edgeSet[e].index>tmp.index;e--);
        edgeSet[b]=edgeSet[e];
        for(;b<e&&edgeSet[b].index<=tmp.index;b++);
        edgeSet[e]=edgeSet[b];
    }
    edgeSet[b]=tmp;
    quickSort(edgeSet,i,b-1);
    quickSort(edgeSet,b+1,j);
}
void createTree(int Cost[][MAXN],int n,int sum){
    //先创建一个闭包
    for(int i=0;i<n;i++){
        set<int>tmp={i};
        Closure.insert(tmp);
    }
    //创建一个边的数组
    vector<edge>edgeSet;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(Cost[i][j]!=0)edgeSet.push_back(edge{i+1,j+1,Cost[i][j]});
        }
    }
    quickSort(edgeSet,0,edgeSet.size()-1);
    for(int i=0;i<edgeSet.size();i++){
        cout<<edgeSet[i].index<<",";
    }
    cout<<endl;
    //连接闭包
    for(int i=0;i<edgeSet.size()&&Closure.size()!=1;i++){
        edge e=edgeSet[i];
        int x1=e.s,y1=e.e,size=0;
        auto r1=Closure.begin(),r2=Closure.begin();
        for(auto j=Closure.begin();j!=Closure.end();j++,size++){
            for(auto k=j->begin();k!=j->end();k++){
                if(*k==x1){
                    r1=j;
                }
                if(*k==y1){
                    r2=j;
                }
            }
        }
        if(r1!=r2){
            set<int>tmp;
            for(int i:*r1){
                tmp.insert(i);
            }
            for(int i:*r2){
                tmp.insert(i);
            }
            Closure.erase(r1);
            Closure.erase(r2);
            Closure.insert(tmp);
            sum+=e.index;
            TheSetOfTree.push_back(e);
        }
    }
    cout<<Closure.size()<<endl;
    cout<<sum<<endl;
    for(auto i : TheSetOfTree){
        cout<<i.e<<"->"<<i.s<<"("<<i.index<<")   ";
    }
    cout<<endl;
}
/*5
0 2 0 6 0
2 0 3 8 5
0 3 0 0 7
6 8 0 0 9
0 5 7 9 0*/
int main(){
    int Cost[MAXN][MAXN];
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>Cost[i][j];
        }
    }
    createTree(Cost,n,0);
    FloorPrint(CreateTree(TheSetOfTree,1));
    return 0;
}

Dijkstra算法:

#define MAXN 50
/*5
0 2 0 6 0
2 0 3 8 5
0 3 0 0 7
6 8 0 0 9
0 5 7 9 0*/
//我用动态规划来做
void Dijkstra(int Cost[][MAXN],int start,int n){
    int theDWON[n];
    for(int i=0;i<n;i++){
        if(i==start){
            theDWON[i]=0;
        }else{
            theDWON[i]=999;
        }
    }
    queue<int>q;
    q.push(start);
    while(!q.empty()){
        int tmp1=q.front();
        q.pop();
        for(int i=0;i<n;i++){
            if(Cost[tmp1][i]!=0){
                theDWON[i]=min(theDWON[i],theDWON[tmp1]+Cost[tmp1][i]);
                if(theDWON[i]!=theDWON[tmp1]+Cost[tmp1][i]) continue;
                q.push(i);
            }
        }
    }
    for(int i=0;i<n;i++) cout<<theDWON[i]<<" ";
    cout<<endl;
}
int main(){
    int Cost[MAXN][MAXN];
    int n=0; cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>Cost[i][j];
        }
    }
    int start;
    cin>>start;
    Dijkstra(Cost,start,n);
    return 0;
}

拓扑排序:(dfs、bfs太简单了,就不写了,用kahn算法)


#define MAXN 50
void Kahn(int Cost[][MAXN],int n){
    int in[n];
    int vis[MAXN]={0};
    vector<int>Topo;
    for(int i=0;i<n;i++){
        int sum=0;
        for(int j=0;j<n;j++){
            if(Cost[i][j]!=0) sum++;
        }
        in[i]=sum;
    }
    stack<int>st;

    for(int i=0;i<n;i++){
        if(in[i]==0){
            vis[i]=1;
            st.push(i);
        }
    }
    while(!st.empty()){
        int tmp=st.top();
        st.pop();
        Topo.push_back(tmp);
        for(int i=0;i<n;i++){
            if(Cost[i][tmp]>0){
                in[i]--;
            }
        }
        for(int i=0;i<n;i++){
            if(in[i]==0&&vis[i]==0){
                vis[i]=1;
                st.push(i);
            }
        }
    }
    for(int i=n-1;i>=0;i--){
        cout<<Topo[i]<<" ";
    }
    cout<<endl;
}
int main(){
    int n=0;
    cin>>n;
    int Cost[MAXN][MAXN];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>Cost[i][j];
        }
    }
    Kahn(Cost,n);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值