/*1.遍历*/
/*(1).广度优先遍历,利用visit数组以及入栈和出栈*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
class TU
{
private:
int vertex;
int spot;
int index;
int str[Max_Size][Max_Size];
int visit[Max_Size];
public:
TU()
{
vertex=spot=0;
index=-1;
}
~TU(){}
void creat(int n,int m)
{
spot=n;//点
vertex=m;//边
for(int i=0;i<spot;i++)
{
for(int j=0;j<spot;j++)
{
str[i][j]=0;
}
}
for(int i=0;i<spot;i++)
{
visit[i]=0;
}
while(++index<vertex)
{
int i,j;
cin>>i>>j;
str[i][j]=str[j][i]=1;
}
}
void pop(int n)
{
int front=0,area=0;
int node[Max_Size]={0};
cout<<n<<" ";
visit[n]=1;
node[front++]=n;//入栈
while(front!=area)
{
int s=node[area++];//出栈
for(int i=0;i<spot;i++)
{
if(str[s][i]==1&&visit[i]!=1)
{
cout<<i<<" ";
node[front++]=i;
visit[i]=1;
}
}
}
}
};
int main()
{
int n,m,a;
cin>>n>>m>>a;
TU p;
p.creat(n,m);
p.pop(a);
}*/
/*(2).深度优先遍历*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
class TU
{
private:
int vertex;
int spot;
int index;
int str[Max_Size][Max_Size];
int visit[Max_Size];
public:
TU()
{
vertex=spot=0;
index=-1;
}
~TU(){}
void creat(int n,int m)
{
spot=n;//点
vertex=m;//边
for(int i=0;i<spot;i++)
{
for(int j=0;j<spot;j++)
{
str[i][j]=0;
}
}
for(int i=0;i<spot;i++)
{
visit[i]=0;
}
while(++index<vertex)
{
int i,j;
cin>>i>>j;
str[i][j]=str[j][i]=1;
}
}
void pop(int v)
{
visit[v]=1;
cout<<v<<" ";
for(int i=0;i<spot;i++)
{
if(str[v][i]==1&&visit[i]!=1)
{
pop(i);
}
}
}
};
int main()
{
int n,m,a;
cin>>n>>m>>a;
TU p;
p.creat(n,m);
p.pop(a);
}*/
/*注:深度与广度遍历出来的结果不一样,深度为前序,广度为层序
比如:4 4 3 0 1 1 2 2 3 1 3结果不一样 ,深度为3102 广度为3120*/
/*2.最小生成树 Prim 和 Kruskal 带有权值*/
/*(1)Prim 算法 利用了结构体*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
struct ShortEdge
{
int lowcost;//权值
int adjvex;//最短边
};
int findmin(ShortEdge shortedge[],int l)
{
int min=10000;
int t=0;
for(int i=0;i<l;i++)
{
if(shortedge[i].lowcost<min&&shortedge[i].lowcost!=0)
{
min=shortedge[i].lowcost;
t=i;
}
}
return t;
}
class Prim
{
private:
int vertex;
int spot;
int index;
int str[Max_Size][Max_Size];
ShortEdge shortedge[Max_Size];
public:
Prim()
{
vertex=spot=0;
index=-1;
}
~Prim(){}
void creat(int n,int m)
{
spot=n;//点
vertex=m;//边
for(int i=0;i<spot;i++)
{
for(int j=0;j<spot;j++)
{
if(i==j)
{
str[i][j]=0;
continue;
}
str[i][j]=10000;
}
}
while(++index<vertex)
{
int i,j,a;
cin>>i>>j>>a;
str[i][j]=str[j][i]=a;
}
}
void pop(int v)
{
for(int i=0;i<spot;i++)
{
shortedge[i].lowcost=str[i][v];
shortedge[i].adjvex=v;
}
shortedge[v].lowcost=0;
cout<<v<<" ";
for(int i=1;i<spot;i++)
{
int k=findmin(shortedge,spot);//找到最小权值边
cout<<k<<" ";
shortedge[k].lowcost=0;
for(int i=0;i<spot;i++)
{
if(shortedge[i].lowcost>str[i][k])
{
shortedge[i].lowcost=str[i][k];
shortedge[i].adjvex=k;
}
}
}
}
};
int main()
{
int n,m,a;
cin>>n>>m>>a;
Prim p;
p.creat(n,m);
p.pop(a);
}*/
/*(2).Kruskal算法 注:1.有对结构体的排序从小到大 2利用parent数组,找到是否能构成一个圆*/
/*!!!!!!放弃!!!!!!!!!,先弄下面的*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
struct ShortEdge
{
int lowcost;//权值
int adjvex;//最短边
};
int findmin(ShortEdge shortedge[],int l)
{
int min=10000;
int t=0;
for(int i=0;i<l;i++)
{
if(shortedge[i].lowcost<min&&shortedge[i].lowcost!=0)
{
min=shortedge[i].lowcost;
t=i;
}
}
return t;
}
class Prim
{
private:
int vertex;
int spot;
int index;
int str[Max_Size][Max_Size];
ShortEdge shortedge[Max_Size];
public:
Prim()
{
vertex=spot=0;
index=-1;
}
~Prim(){}
void creat(int n,int m)
{
spot=n;//点
vertex=m;//边
for(int i=0;i<spot;i++)
{
for(int j=0;j<spot;j++)
{
if(i==j)
{
str[i][j]=0;
continue;
}
str[i][j]=10000;
}
}
while(++index<vertex)
{
int i,j,a;
cin>>i>>j>>a;
str[i][j]=str[j][i]=a;
}
}
void pop(int v)
{
for(int i=0;i<spot;i++)
{
shortedge[i].lowcost=str[i][v];
shortedge[i].adjvex=v;
}
shortedge[v].lowcost=0;
cout<<v<<" ";
for(int i=1;i<spot;i++)
{
int k=findmin(shortedge,spot);//找到最小权值边
cout<<k<<" ";
shortedge[k].lowcost=0;
for(int i=0;i<spot;i++)
{
if(shortedge[i].lowcost>str[i][k])
{
shortedge[i].lowcost=str[i][k];
shortedge[i].adjvex=k;
}
}
}
}
};
int main()
{
int n,m,a;
cin>>n>>m>>a;
Prim p;
p.creat(n,m);
p.pop(a);
}*/
/*3.最短路径 Dijkstra 和 Floyd 注:此时的图为有向图 单向,或者看清题干,有时为单向,有时为双向,下面的代码为单向*/
/*(1)Floyd算法 注:利用三重循环*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size = 100;
class Floyd
{
private:
int vertex;
int spot;
int index;
int str[Max_Size][Max_Size];
public:
Floyd()
{
vertex = spot = 0;
index = -1;
}
~Floyd() {}
void creat(int n, int m)
{
spot = n; //点
vertex = m; //边
for(int i = 0; i < spot; i++)
{
for(int j = 0; j < spot; j++)
{
if(i == j)
{
str[i][j] = 0;
continue;
}
str[i][j] = 10000;
}
}
while(++index < vertex)
{
int i, j, a;
cin >> i >> j >> a;
str[i][j] = a;
}
}
void pop()
{
int v1, v2;
cin >> v1 >> v2;
for(int i = 0; i < spot; i++)
{
for(int j = 0; j < spot; j++)
{
for(int k = 0; k < spot; k++)
{
if(str[i][j] > str[i][k] + str[k][j])
{
str[i][j] = str[i][k] + str[k][j];
}
}
}
}
cout << str[v1][v2];
}
};
int main()
{
int n, m;
cin >> n >> m;
Floyd p;
p.creat(n, m);
p.pop();
}*/
/*(2)Dijkstra*/
/*!!!!!!!没有写!!!!!!!!*/
/*3.关键路径 拓扑排序*/
/*拓扑排序*/
/*
/*1.思想:输出没有入度的顶点
2.构造:采用邻接表的方法构造图
对没有入度的顶点可以设置入栈的操作*/
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
/*邻接表的构造*/
struct ArcNode//定义边表结点
{
int adjvex;//邻接点域
ArcNode *next;
};
struct VertexNode//定义顶点表结点
{
int vertex;
int in;//入度
ArcNode *firstedge;
};
class ALGraph
{
private:
VertexNode adjlist[Max_Size];
int spot,vertex,index;
int front,area;
int str[Max_Size];
public:
ALGraph()
{
spot=vertex=front=area=0;
index=-1;
}
~ALGraph(){}
void creatList(int n,int m)//构造邻接表
{
spot=n;
vertex=m;
for(int i=0;i<spot;i++)
{
adjlist[i].vertex=i;
adjlist[i].in=0;
adjlist[i].firstedge=NULL;
}
while(++index<vertex)
{
int i,j;
cin>>i>>j;
ArcNode *s=new ArcNode;
s->adjvex=j;
s->next=adjlist[i].firstedge;
adjlist[i].firstedge=s;
adjlist[j].in++;
}
}
void TopSort()//利用入栈出栈
{
for(int i=0;i<spot;i++)
{
if(adjlist[i].in==0)
{
str[front++]=i;
}
}
while(front!=0)
{
int k=str[--front];
cout<<adjlist[k].vertex<<" ";area++;
ArcNode *p=adjlist[k].firstedge;
while(p!=NULL)
{
int j;
j=p->adjvex;
adjlist[j].in--;
if(adjlist[j].in==0)
{
str[front++]=j;
}
p=p->next;
}
}
if(area<spot)
{
cout<<"有回路"<<endl;
}
}
};
int main()
{
ALGraph p;
p.creatList(6,9);
p.TopSort();
return 0;
}*/
/*关键路径
/*
思路:(len为边的权值)
事件最早发生时间:ve[k](ve为点),即求出到达该点最长的路径
ve[0]=0;
ve[k]=max{ve[k]+len<vj,vk>}
事件最迟发生时间:vl[k](vl为点),即从后面求,找到最小的路径
vl[n-1]=ve[n-1];
vl[k]=min{vl[j]-len<vk,vj>}
活动最早开始的时间:ee[i](ee为边),即等于该边的始点
ee[i]=ve[k] 即每条边的起点
活动最迟开始的时间:el[i](el为边),即等于该边的终点减去边的权值
el[i]=vl[i]-len<vk,vj>;
关键路径为:ee[i]==el[i]
*/
#include<string.h>
#include<iostream>
#include<stdlib.h>
const int Max_Size=100;
using namespace std;
struct Vel
{
int from,to;
int weight;
};
class AOE
{
private:
int spot,vertex;
int index;
int node[Max_Size][Max_Size];
int ve[Max_Size],vl[Max_Size];
int ee[Max_Size],el[Max_Size];
Vel vel[Max_Size];
public:
AOE()
{
spot=vertex=0;
index=-1;
}
~AOE(){}
void push(int n,int m)
{
spot=n;
vertex=m;
for(int i=0;i<spot;i++)
{
for(int j=0;j<spot;j++)
{
node[i][j]=-1;
}
}
while(++index<vertex)
{
int i,j,a;
cin>>i>>j>>a;
node[i][j]=a;
vel[index].from=i;
vel[index].to=j;
vel[index].weight=a;
}
}
int k;
void bulidve()//建立ve,即事件最早发生的时间
{
ve[0]=0;
for(int i=1;i<spot;i++)
{
ve[i]=0;
int max=0;
for(int j=0;j<spot;j++)
{
if(node[j][i]+ve[j]>max&&node[j][i]!=-1)
{
max=node[j][i]+ve[j];
}
}
ve[i]=max;
}
}
void bulidvl()//建立事件最迟发生的时间
{
vl[spot-1]=ve[spot-1];
for(int i=spot-2;i>=0;i--)
{
vl[i]=0;
int min=10000;
for(int j=spot-1;j>=0;j--)
{
if(vl[j]-node[i][j]<min&&node[i][j]!=-1)
{
min=vl[j]-node[i][j];
}
}
vl[i]=min;
}
}
void bulidee()//建立活动最早开始时间
{
for(int i=0;i<vertex;i++)
{
int k=vel[i].from;
ee[i]=ve[k];
}
}
void bulidel()
{
for(int i=vertex-1;i>=0;i--)
{
int k=vel[i].to;
el[i]=vl[k]-vel[i].weight;
}
}
void pop()//ee==el时,该边为关键路径
{
int a[100]={0},k=0;
for(int i=0;i<vertex;i++)
{
if(ee[i]==el[i])
{
a[k]=i;
cout<<i<<" ";
k++;
}
}
}
};
int main()
{
AOE p;
p.push(9,11);
p.bulidve();
p.bulidvl();
p.bulidee();
p.bulidel();
p.pop();
return 0;
}*/