问题 A: 关键路径
时间限制: 1 Sec 内存限制: 128 MB
提交: 261 解决: 90
[提交][状态][讨论版][命题人:外部导入]
题目描述
描述:
图的连接边上的数据表示其权值,带权值的图称作网。
上图可描述为顶点集为(a,b,c,d,e)
边集及其权值为(始点,终点 权值):a b 3
a c 2
b d 5
c d 7
c e 4
d e 6
网的源点是入度为0的顶点,汇点是出度为0的顶点。网的关键路径是指从源点到汇点的所有路径中,具有最大路径长度的路径。上图中的关键路径为a->c->d->e,其权值之和为关键路径的长度为15。
本题的要求是根据给出的网的邻接矩阵求该网的关键路径及其长度。
输入
第一行输入一个正整数n(1<=n<=5),其代表测试数据数目,即图的数目
第二行输入x(1<=x<=15)代表顶点个数,y(1<=y<=19)代表边的条数
第三行给出图中的顶点集,共x个小写字母表示顶点
接下来每行给出一条边的始点和终点及其权值,用空格相隔,每行代表一条边。
输出
第一个输出是图的关键路径(用给出的字母表示顶点, 用括号将边括起来,顶点逗号相隔)
第二个输出是关键路径的长度
每个矩阵对应上面两个输出,两个输出在同一行用空格间隔,每个矩阵的输出占一行。
样例输入
2 5 6 abcde a b 3 a c 2 b d 5 c d 7 c e 4 d e 6 4 5 abcd a b 2 a c 3 a d 4 b d 1 c d 3
样例输出
(a,c) (c,d) (d,e) 15 (a,c) (c,d) 6
#include<bits/stdc++.h>
using namespace std;
const int maxn=20;
const int INF=0x3fffffff;
struct node{
int v,w;
node(int x,int y):v(x),w(y){ };
};
vector<node> adj[maxn];
vector<int> ans[maxn];
stack<int> topoSeq;
int n,m,ve[maxn],vl[maxn];
int inDegree[maxn];
char str[maxn];
map<char,int> mp;
bool topologicalSort(){
memset(ve,0,sizeof(ve));
queue<int> q;
for(int i=0;i<n;i++){
if(inDegree[i]==0) q.push(i);
}
while(q.size()){
int u=q.front();
q.pop();
topoSeq.push(u);
for(int i=0;i<adj[u].size();++i){
int v=adj[u][i].v;//u的i号后继结点编号为v
int w=adj[u][i].w;
--inDegree[v];
if(inDegree[v]==0) q.push(v);
if(ve[u]+w>ve[v]) ve[v]=ve[u]+w;
}
}
if(topoSeq.size()==n) return true;
else return false;
}
int criticalPath(){
if(topologicalSort()==false) return -1;//不是有向无环图,返回-1
int maxlength=0;
for(int i=0;i<n;i++){
if(ve[i]>maxlength) maxlength=ve[i];
}
fill(vl,vl+maxn,maxlength);
while(topoSeq.size()){
int u=topoSeq.top();
topoSeq.pop();
for(int i=0;i<adj[u].size();++i){
int v=adj[u][i].v;
int w=adj[u][i].w;
if(vl[v]-w<vl[u]) vl[u]=vl[v]-w;
}
}
for(int i=0;i<n;i++){
ans[i].clear();
}
for(int u=0;u<n;++u){
for(int i=0;i<adj[u].size();++i){
int v=adj[u][i].v;
int w=adj[u][i].w;
int e=ve[u];//活动的最早开始时间e
int l=vl[v]-w;//最迟开始时间l
if(e==l) ans[u].push_back(v);
}
}
int s;
for(int i=0;i<n;++i){
if(ve[i]==0){
s=i;
break;
}
}
while(ans[s].size()){
printf("(%c,%c) ",str[s],str[ans[s][0]]);
s=ans[s][0];
}
return maxlength;
}
int main(){
int n1,w;
char a,b;
while(~scanf("%d",&n1)){
for(int i=0;i<n1;i++){
for(int j=0;j<n;++j)
adj[j].clear();
memset(inDegree,0,sizeof(inDegree));
scanf("%d %d",&n,&m);
scanf("%s",str);
mp.clear();
for(int j=0;j<n;++j) mp[str[j]]=j;
for(int j=0;j<m;j++){
getchar();
scanf("%c %c %d",&a,&b,&w);
adj[mp[a]].push_back(node(mp[b],w));
++inDegree[mp[b]];
}
int length=criticalPath();
printf("%d\n",length);
}
}
return 0;
}