题目链接-P1807
这道题的最简单的解法应该是将初始给的权值全部取负,然后对给定的图跑任意一个最短路的板子,将得到的“最短路长度”再取负得到的就是最终的答案
但是因为在学习拓扑排序,就跟着大佬的拓扑思路写了一遍拓扑的解,感觉还是有一些收获的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int HASH=131;
int a[maxn];
int b[maxn];
int degree[maxn];
int vis[maxn];
int dis[maxn];
vector<node> v[maxn];
struct node
{
int to,cost;
};
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y,dis;
cin>>x>>y>>dis;
v[x].push_back({y,dis});
degree[y]++;
}
vis[1]=1;//给定1染色
dis[n]=-1;//赋初始值为-1,不连通时其值不改变,方便直接输出答案
queue<int> q;
for(int i=1;i<=n;i++)
{
if(!degree[i])
{
q.push(i);
}
}
while(!q.empty())
{
int tmp=q.front();
q.pop();
int len=v[tmp].size();
for(int i=0;i<len;i++)
{
if(--degree[v[tmp][i].to]==0)
{
q.push(v[tmp][i].to);
}
if(vis[tmp])//检查是否与1连通(是否被染色)
{
if(dis[v[tmp][i].to]<dis[tmp]+v[tmp][i].cost)//最短路思想
dis[v[tmp][i].to]=dis[tmp]+v[tmp][i].cost;
vis[v[tmp][i].to]=1;//(将该点染色)
}
}
}
cout<<dis[n]<<endl;
return 0;
}