邻接表:
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;
}