这题最开始给你了N个点,M条边,边是单向边,问不指定起点和终点,最长路是什么???
脑补一下,不定起点和终点的最短路,用弗洛伊德算法搞一搞,但是。。。那个垃圾算法的复杂度是N^3的,但是这个算法的M高达5000,直接放弃
仔细想想,可以用剪纸+dijstra做,但是需要改变一下边权,distra求的是最短路,但是我们要的是最长路这个怎么办呢???
其实可以把边权变成负数,然后把边的权值设置为正的无穷大,那么我们只需要求一个最短路,那么由于权值为负数,这个最短路的值越小,它的相反-----路径之和最大即可
最后防止超时,用一个BOOK数值标记这个点是否有祖先,即它是不是根节点就好了,最后判断如果是跟节点再用dijstra堆优化一下就行
#include<bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int MAX_V = 5006; struct edge { int to,cost; }; typedef pair<int, int> P; int V; int n,m,st,ed; int d[MAX_V]; vector<edge> G[MAX_V]; int ans; void dijkstra(int s) { priority_queue<P,vector<P>,greater<P> >que; for (int i=1;i<=n;i++){ d[i]=INF; } d[s]=0; que.push(P(0,s)); while(!que.empty()) { // cout<<"---"<<endl; P p = que.top(); que.pop(); int v=p.second; if (d[v]<p.first)continue; for (int i=0; i<G[v].size(); i++) { edge e=G[v][i]; if (d[e.to] > d[v]+e.cost) { d[e.to] = d[v]+e.cost; que.push(P(d[e.to],e.to)); } } } for (int i=1;i<=n;i++){ //cout<<d[i]<<endl; ans=min(ans,d[i]); } // cout<<ans<<endl; } int main() { int book[5006]; while(~scanf("%d%d",&n,&m)){ int u,v,w; memset(book,0,sizeof(book)); for (int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); book[v]=1; edge s; s.cost=-w; s.to=v; G[u].push_back(s); } for (int i=1;i<=n;i++){ if (book[i]==0){ dijkstra(i); } } printf("%d ",-ans); } return 0; }