题意给你一个有向图,求图中非重叠的最长路
思路这个,看起来是用拓扑排序+spfa做,但是其实(我不会,队友写的)主要是对spfa理解不深刻,平时都是抄模板,导致的自己不会,好好想了想,spfa是求单元最短路(因为怎么回事呢?单源的源点的dis是0,多源的就是源点都是0,然后dis从小于换成大于就好了,因为spfa是bfs思想,所以在更新的过程中,保留dis的最大值,最后撸一遍就好了)
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 1e4 + 10;
typedef long long LL;
int pre[N * 2] , other[N * 2] , last[N * 2] , all = -1 , cost[N * 2] , n;
bool ind[N] , inq[N];
queue<int> q;
LL dis[N];
void build(int x , int y , int w)
{
pre[++all] = last[x];
last[x] = all;
other[all] = y;
cost[all] = w;
}
void spfa()
{
int x = 0;
for(int i = 1 ; i <= n ; i++){
if(ind[i] == false) q.push(i) , x = i , dis[i] = 0 , inq[i] = 1;
else dis[i] = -(1 << 30);
}
while(!q.empty()){
int now = q.front();
q.pop();
int ed = last[now];
while(ed != -1){
int dr = other[ed];
if(dis[now] + cost[ed] > dis[dr]){
dis[dr] = dis[now] + cost[ed];
if(inq[dr] == 0) inq[dr] = 1 , q.push(dr);
}
ed = pre[ed];
}
inq[now] = 0;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
while(!q.empty()) q.pop();
memset(inq , 0 , sizeof(inq));
memset(ind , 0 , sizeof(ind));
int m;
scanf("%d %d",&n , &m);
all = -1;
memset(last , -1 , sizeof(last));
for(int i = 1 ; i <= m ; i++){
int x , y , w;
scanf("%d %d %d",&x , &y , &w);
build(x , y , w);
ind[y] = true;
}
spfa();
LL sum = 0;
for(int i = 1 ; i <= n ; i++){
sum = max(sum , dis[i]);
}
printf("%d\n",sum);
}
return 0;
}
这个题,交不了,所以只能自己yy运行,应该是可以的。
3591

被折叠的 条评论
为什么被折叠?



