PTA 数据结构与算法题目集(中文)5-11 关键活动 (30分)

#include
#include
#include
using namespace std;
/*
关键路径最大值 
用dp[]记录点的间距
先将入度为0的点加入队列,从入度为0的点开始,不断延伸
将下一点的距离置为前置点的最大距离,并将选过点的入度-1
重复将入度为0的点加入队列,直到没有点入队为止,再筛选出最大的距离


关键路径的路径
先将出度为0的点加入队列,用vis[]记录是否加入过队列
从队首开始筛选,判断与该点相连的点是否满足dp[front]-edge[i][front]=dp[i]
满足将该条路径加入s,同时若该点为入过队,入队,重复直到不再有点入队 
*/ 
struct cow
{
int v;
int u;
}s[101*101];//记录关键路径 
int n,m,ed;//n个顶点,m条边,任务完成最大时间所在任务点 
int edge[101][101];//记录任务所耗时间 
int dis[101];//记录入度点 
int vis[101];//记录是否有加入 
int dp[101];//记录各任务点完成所需时间 
int edgetime[101][101];//记录任务输入顺序 
bool cmp(cow a,cow b)//进行这个奇怪的排序,优先按照任务起始点从小到大排,起始点相同时,按与输入相反顺序输入 
{
if(a.v==b.v)return edgetime[a.v][a.u]>edgetime[b.v][b.u];
return a.v }
void init()//初始化各数组 
{
for(int i=1;i<=n;i++)
{
dis[i]=vis[i]=dp[i]=0;
for(int j=1;j<=n;j++)
edge[i][j]=0;
}
}
void rd()//记录入度 
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(edge[i][j])dis[j]++;
}
int topsort()
{
rd();
queuep;
int t=0,ti=1;//t判断完成了几个任务点,ti判断是否有任务点加入 
while(ti) 
{
ti=0;
for(int i=1;i<=n;i++)//将入度为0且为加入过队列的点加入队列 
{
if(dis[i]==0&&vis[i]==0)
{
p.push(i);
vis[i]=1;
t++;
ti=1;
}
}
while(!p.empty())
{
int x=p.front();
p.pop();
for(int i=1;i<=n;i++)
{
if(edge[x][i])//选过这条路,去掉,入度-1 
{
if(dp[x]+edge[x][i]>dp[i])//选出这个任务点的前置任务最迟完成时间 
dp[i]=dp[x]+edge[x][i];
dis[i]--;
}
}
}
}
if(t==n)//若t==n说明所有的任务点都已完成 ,则,选出最迟完成的任务 
{
int max=0;
for(int i=1;i<=n;i++)
if(dp[i]>max)
{
max=dp[i];
ed=i;
}
return max;
}
return 0;
}
void topprint()//输出关键路径 
{
int t=0;//记录有几条关键边 
queuep;
for(int i=1;i<=n;i++)//初始化 
vis[i]=0;
for(int i=1;i<=n;i++)//将任务完成最迟的点加入队列,并将加入队列标志置1 
{
if(dp[i]==dp[ed])
{
vis[i]=1;
p.push(i);
}
}
while(!p.empty())//判断关键任务是否已全部选出 
{
int x=p.front();
p.pop();
for(int i=1;i<=n;i++)
{
if(edge[i][x])
{
if(dp[x]-edge[i][x]==dp[i])//若i->x为关键路径则选出 
{
s[t].v=i;
s[t++].u=x;
if(!vis[i])//任务点为选过则加入队列 
p.push(i);
vis[i]=1;
}
}
}
}
sort(s,s+t,cmp);
for(int i=0;i printf("%d->%d\n",s[i].v,s[i].u);
}
int main()
{
scanf("%d %d",&n,&m);
init();
for(int i=0;i {
int v,u,cost;
scanf("%d %d %d",&v,&u,&cost);
edge[v][u]=cost;
edgetime[v][u]=i;//记录任务输入时间 
}
int k=topsort();
printf("%d\n",k);
if(k)topprint();
return 0;
}

你可能感兴趣的:(PTA 数据结构与算法题目集(中文)5-11 关键活动 (30分))