abc--280--F
阿新 • • 發佈:2022-12-04
題目大意
給你一個圖,查詢兩個點的最長路
邊權是正著走是正數,反著走為負數
無法到達為nan,無窮大為inf
注意:會有重邊和自環
思路
用並查集劃分連通塊,用dfs對連通塊內進行走圖
如果到達這個點兩次的路徑是不一樣的,那大的那一端作為正著走,小的那一端反著走,就一定能構成一個正環
只要出現正環,那這一整個連通分量都是inf
程式碼
#include <bits/stdc++.h> using namespace std; using ll=long long; const int M=1e5+5; inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } int h[M],ne[M<<1],e[M<<1],w[M<<1],tot; void add(int from,int to,int wi) { e[++tot]=to; w[tot]=wi; ne[tot]=h[from]; h[from]=tot; } ll dis[M]; int f[M],c[M],cnt; void dfs(int now) { c[now]=cnt; for(int i=h[now];i;i=ne[i]) { int to=e[i]; if(c[to]) { if(dis[to]!=dis[now]+w[i])f[cnt]=1; } else { dis[to]=dis[now]+w[i]; dfs(to); } } } int main() { int n=read(),m=read(),q=read(); while(m--) { int x=read(),y=read(),wi=read(); add(x,y,wi); add(y,x,-wi); } for(int i=1;i<=n;i++) if(c[i]==0)cnt++,dfs(i); while(q--) { int x=read(),y=read(); if(c[x]!=c[y])cout<<"nan\n"; else if(f[c[x]])cout<<"inf\n"; else cout<<dis[y]-dis[x]<<endl; } return 0; }