目录
一. 问题描述
Problem Description
求最短时间和所有的关键活动,注意多起点多终点
二. 题解代码
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 100 + 7;
struct Edge{
int from,to,next,time,id;
}edge[maxn*1000],edge2[maxn*1000];
int n,m,tot,tot2,head[maxn],in[maxn],ve[maxn],out[maxn],head2[maxn],vl[maxn],Max;
void addEdge(int a,int b,int c,int d){
edge[tot].id = d;edge[tot].from = a;edge[tot].to = b;edge[tot].time = c;edge[tot].next = head[a],head[a] = tot++;
}
void addEdge2(int a,int b,int c){
edge2[tot2].from = a;edge2[tot2].to = b;edge2[tot2].time = c;edge2[tot2].next = head2[a],head2[a] = tot2++;
}
struct Node{
int s,e,id;
bool operator <(const Node &another)const{
if(s==another.s)return id < another.id;
return s > another.s;
}
Node(int a,int b,int c):s(a),e(b),id(c) {}
};
bool TupoSort(){
queue<int> que;
memset(ve,0,sizeof(ve));
for(int i = 1;i<=n;i++){
if(in[i]==0)que.push(i);
//cout<<ve[i]<<" "<<in[i]<<endl;
}
int cnt = 0;
while(!que.empty()){
cnt++;
int p = que.front();
que.pop();
for(int i = head[p];~i;i = edge[i].next){
in[edge[i].to]--;
if(ve[edge[i].to] < ve[p] + edge[i].time){
ve[edge[i].to] = ve[p] + edge[i].time;
}
if(!in[edge[i].to])que.push(edge[i].to);
}
}
if(cnt!=n)return false;
return true;
}
void ReTupoSort(){
memset(vl,INF,sizeof(vl));
queue<int> que;
for(int i = 1;i<=n;i++){
if(out[i]==0){
que.push(i);
vl[i] = Max;
}
}
while(!que.empty()){
int p = que.front();
que.pop();
for(int i = head2[p];~i;i = edge2[i].next){
out[edge2[i].to]--;
if(vl[edge2[i].to] > vl[p] - edge2[i].time){
vl[edge2[i].to] = vl[p] - edge2[i].time;
}
if(!out[edge2[i].to])que.push(edge2[i].to);
}
}
}
int main()
{
tot = tot2 = 0;
memset(head,-1,sizeof(head));
memset(head2,-1,sizeof(head2));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d%d",&n,&m);
for(int i = 0;i<m;i++){
int a,b,v;
scanf("%d%d%d",&a,&b,&v);
addEdge(a,b,v,i);
addEdge2(b,a,v);
in[b]++;
out[a]++;
}
if(!TupoSort())printf("0\n");
else{
Max = -1;
for(int i = 1;i<=n;i++){
if(out[i]==0)Max = max(Max,ve[i]);
}
printf("%d\n",Max);
ReTupoSort();
priority_queue<Node> que;
for(int i = 1;i<=n;i++){
if(ve[i]!=vl[i])continue;
for(int j = head[i];~j;j = edge[j].next){
if(ve[i]==vl[edge[j].to] - edge[j].time){
que.push(Node(i,edge[j].to,edge[j].id));
}
}
}
while(!que.empty()){
Node node = que.top();
que.pop();
printf("%d->%d\n",node.s,node.e);
}
}
}