拓扑排序
vector<int> G[MAXN];
int inDegree[MAXN]={0}; //入度
bool topSort(){
int num=0;
//用priority_queue可以保证先输出较小的节点
priority_queue<int,vector<int>,greater<int> >q;
//将入度为0的节点入队
for(int i=0;i<n;i++){
if(inDegree[i]==0){
q.push(i);
}
}
while(!q.empty()){
int u=q.top();
printf("%d ",u);
q.pop();
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
inDegree[v]--;//相邻的顶点的入度减1
if(inDegree[v]==0){//将入度为0的节点入队
q.push(v);
}
}
G[u].clear();//清除以u为尾的弧
num++;
}
if(num==n)return true;
else return false;//拓扑序列顶点数小于n,拓扑排序失败
}
关键路径:
int inDegree[MAXN]={0};//入度
stack<int> topOrder;//存放拓扑序列
int ve[MAXN]={0};//节点最早开始时间
int vl[MAXN];//节点最晚结束时间
vector<Node> G[MAXN];//图的邻接表
vector<pair<int,int> > ans;//保存结果路径
//先拓扑排序
bool topSort(){
queue<int> q;
//将所有入度为0的入队列
for(int i=1;i<=n;i++){
if(inDegree[i]==0){
q.push(i);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
topOrder.push(u);//加入拓扑序列中
for(int i=0;i<G[u].size();i++){
int v=G[u][i].v;
inDegree[v]--;//所有相邻节点的入度减1
if(inDegree[v]==0){
q.push(v);//入度为0,入队列
}
//计算ve[]数组
if(ve[u]+G[u][i].w>ve[v]){
ve[v]=ve[u]+G[u][i].w;
}
}
}
if(topOrder.size()==n)return true;
else return false;
}
int CriticalPath(){
if(topSort()==false) return -1;
//找到最长距离(即汇点对应的最早开始时间ve)
int MAX=-1;
for(int i=1;i<=n;i++){
if(ve[i]>MAX){
MAX=ve[i];
}
}
//初始化vl数组
fill(vl,vl+MAXN,MAX);
while(!topOrder.empty()){
int u=topOrder.top();
topOrder.pop();
//更新vl[]数组
for(int i=0;i<G[u].size();i++){
int v=G[u][i].v;
if(vl[v]-G[u][i].w<vl[u]){
vl[u]=vl[v]-G[u][i].w;
}
}
}
//遍历所有活动
for(int u=1;u<=n;u++){
for(int i=0;i<G[u].size();i++){
int v=G[u][i].v,w=G[u][i].w;
int e=ve[u],l=vl[v]-w;
if(e==l){//e=l的活动是关键活动
ans.push_back(make_pair(u,v));
}
}
}
return MAX;//返回关键路径长度
}
Dijkstra 单源最短路径+DFS搜索结果路径:
int n;//顶点数
int optvalue;//第二标尺最优值
int G[MAXV][MAXV];
int d[MAXV];//起点到达各点的最短路径长度
bool vis[MAXV]={false};//标记数组,true表示已访问
vector<int> pre[MAXV];//最短路径前一个顶点
vector<int>path,tempPath; //最优路径,临时路径
void Dijkstra(int s){//s为起点
fill(d,d+MAXV,INF);//初始到所有点的距离为INF
d[s]=0;
for(int i=0;i<n;i++){//循环n次
//找到未访问的顶点中d[]最小的
int u=-1,MIN=INF;
for(int j=0;j<n;j++){
if(vis[j]==false&&d[j]<MIN){
u=j;
MIN=d[j];
}
}
//找不到
if(u==-1)return ;
//找到之后标记为已访问
vis[u]=true;
//更新d[]
for(int v=0;v<n;v++){
if(vis[v]==false&&G[u][v]!=INF){
if(d[u]+G[u][v]<d[v]){
d[v]=d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
} else if(d[u]+G[u][v]==d[v]){
pre[v].push_back(u);
}
}
}
}
}
int st=0;
void DFS(int v){//v为当前访问节点
if(v==st){//st为路径起点
tempPath.push_back(v);
int value;
/* 计算value*/
//如果value优于optvalue,更新
if(value>optvalue){
optvalue=value;
path=tempPath;
}
tempPath.pop_back();
return;
}
tempPath.push_back(v);
for(int i=0;i<pre[v].size();i++){
DFS(pre[v][i]);
}
tempPath.pop_back();
}
Floyd最短路径:
int dis[MAXN][MAXN];//表示顶点i和顶点j的最短距离
//Floyd初始化
fill(dis[0],dis[0]+MAXV*MAXV,INF);
for(int i=0;i<n;i++){
dis[i][i]=0;
}
void Floyd(){
for(int k=0;k<n;i++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(dis[i][k]!=INF&&dis[k][j]!=INF&&dis[i][k]+dis[k][j]<dis[i][j]){
dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
}
}