Time Limit:10000MS Memory Limit:65536K
Total Submit:130 Accepted:81
Case Time Limit:1000MS
Description
某工厂发现厂里的机器在生产产品时要消耗大量的原材料,也就是说,有大量的原材料变成了废物。因此厂里想找出消耗原材料最大的一条生产线路进行改造,以降低成本。厂里的生产线路是一个有向无环网络,有
台机器分别代表网络中的
个结点。弧
表示原材料从机器i传输到机器j的损耗数量。
Input
第一行是两个整数
,
,分别表示网络的结点个数和弧数。第二行至
行,每行三个整数
,
,
,表示弧上的损耗为
。
Output
仅一个整数,为损耗最大的线路的损耗量。
Sample Input
5 5
1 2 2
2 4 9
1 3 7
3 4 1
4 5 6
Sample Output
17
解题思路
算法详情请见:SPAF.
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
using namespace std;
const int INF=0X7fffffff;
int h=0,t=1,v[100000],q[100000],n,m,c,dis[100000],head[100000],k,b[100000],maxn,ans=0;
//dis[i]记录从起点s到i的最短路径,v记录一个点是否现在存在在队列中,q是队列
int x,y,z;
struct c{//邻接表记录连接i,j的边,让后面不用枚举所有点
int x,w,next;
}a[100000];
void bfs(int s)
{
int x;
memset(v,0,sizeof(v));
memset(dis,0,sizeof(dis));
memset(q,0,sizeof(q));
v[s]=1;
q[1]=s;
dis[s]=0;
h=0;
t=1;
do{
h++;
x=q[h];//头指针向下移一位,取出指向的点u
for(int i=head[x];i;i=a[i].next)//注意不要去枚举所有点,用数组模拟邻接表存储
{
if(dis[x]+a[i].w>dis[a[i].x])//[松弛操作](https://baike.baidu.com/item/%E6%9D%BE%E5%BC%9B%E6%93%8D%E4%BD%9C/7554089?fr=aladdin).
{
dis[a[i].x]=dis[x]+a[i].w;
if(!v[a[i].x])//队列中不存在v点,v入队
{
v[a[i].x]=1;
t++;
q[t]=a[i].x;//尾指针下移一位,v入队
}
}
}
v[x]=0;
}while(h<t);
}
void add(int x,int y,int z){
++k;
a[k].x=y;
a[k].w=z;
a[k].next=head[x];
head[x]=k;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
for(int i=1;i<=n;i++)
{
maxn=0;
bfs(i);
for(int j=1;j<=n;j++)
if(dis[j]>ans)
ans=dis[j];
}
cout<<ans;
}