做法:tarjan缩点,但是不用拓扑而是dfs,这么做有bug吗
#include<bits/stdc++.h>
using namespace std;
struct edge{
int from,to;
}ed[1000050];
int n,m,v[100050],x,y,z,dfn[100050],low[100050],kth,scc[100050],nth,cnt,mx[100050],mn[100050],maxn[100050],minn[100050],ans;
int st[100050],tp;
bool flag[100050],can_arrive[100050];
vector<int> T[100050],new_T[100050];
queue<int> q;
void dfs(int no){
dfn[no]=low[no]=++kth;
st[++tp]=no;
for(unsigned int i=0;i<T[no].size();i++){
if(dfn[T[no][i]]==0){
dfs(T[no][i]);
low[no]=min(low[no],low[T[no][i]]);
}else low[no]=min(low[no],dfn[T[no][i]]);
}if(dfn[no]==low[no]){
nth++;
while(st[tp]!=no){
scc[st[tp]]=nth;
mx[nth]=max(mx[nth],v[st[tp]]);
mn[nth]=min(mn[nth],v[st[tp]]);
tp--;
}scc[st[tp]]=nth;
mx[nth]=max(mx[nth],v[st[tp]]);
mn[nth]=min(mn[nth],v[st[tp]]);
tp--;
}
}
void dfs2(int no){
minn[no]=min(minn[no],mn[no]);
maxn[no]=max(maxn[no],mx[no]);
flag[no]=1;
if(no==scc[n]){
can_arrive[no]=1;
return;
}
for(unsigned int i=0;i<new_T[no].size();i++){
if(flag[new_T[no][i]]==0){
dfs2(new_T[no][i]);
if(can_arrive[new_T[no][i]]){
can_arrive[no]=1;
maxn[no]=max(maxn[no],maxn[new_T[no][i]]);
minn[new_T[no][i]]=min(minn[new_T[no][i]],minn[no]);
}
}
}
}
int main()
{
memset(mn,0x7f,sizeof(mn));
memset(minn,0x7f,sizeof(mn));
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>v[i];
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
T[x].push_back(y);
cnt++;
ed[cnt].from=x;
ed[cnt].to=y;
if(z==2){
T[y].push_back(x);
cnt++;
ed[cnt].from=y;
ed[cnt].to=x;
}
}for(int i=1;i<=n;i++)
if(dfn[i]==0)dfs(i);
for(int i=1;i<=cnt;i++)
if(scc[ed[i].from]!=scc[ed[i].to])
new_T[scc[ed[i].from]].push_back(scc[ed[i].to]);
dfs2(scc[1]);
for(int i=1;i<=nth;i++)
if(can_arrive[i])ans=max(ans,maxn[i]-minn[i]);
cout<<ans<<endl;
return 0;
}