略
==只是spfa跑的时候要用递归(?)版的 普通的判负环要超时啊啊啊啊啊啊啊
#include<bits/stdc++.h> using namespace std; #define Max(x,y) ((x)>(y)?(x):(y)) #define Min(x,y) ((x)<(y)?(x):(y)) const int N=600+10,M=100000+10,inf=0x3f3f3f3f; int n,m1,m2,mp[N][N],ans=0; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int head[N],tot=0; struct edge{int v,w,nxt;}e[M<<1]; void add(int u,int v,int w){ e[++tot]=(edge){v,w,head[u]},head[u]=tot; } int idx=0,Bcnt=0,dfn[N],low[N],bl[N],sz[N]; stack<int>s;bool inst[N]; void tarjan(int u){ dfn[u]=low[u]=++idx,s.push(u),inst[u]=1; for(int i=head[u],v;i;i=e[i].nxt) { if (!dfn[v=e[i].v]) tarjan(v),low[u]=Min(low[u],low[v]); else if (inst[v]&&dfn[v]<low[u]) low[u]=dfn[v]; } if(low[u]==dfn[u]){ ++Bcnt; while(233){ int v=s.top();s.pop(); bl[v]=Bcnt,++sz[Bcnt],inst[v]=0; if(v==u) break; } } } int dis[N][N],cnt[N];bool vis[N]; /*queue<int>q; bool spfa(int s) { memset(dis[s],inf,sizeof(dis[s])); memset(cnt,0,sizeof(cnt)); memset(vis,0,sizeof(vis)); dis[s][s]=0,q.push(s),vis[s]=1; while (!q.empty()) { int u=q.front();q.pop(),vis[u]=0; for(int i=head[u],v,w;i;i=e[i].nxt){ if (bl[s]!=bl[v=e[i].v]) continue; if (dis[s][u]+(w=e[i].w)<dis[s][v]) { dis[s][v]=dis[s][u]+w,cnt[v]=cnt[u]+1; if (cnt[v]>sz[bl[s]]) return 1; if (!vis[v]) vis[v]=1,q.push(v); } } } return 0; } */ bool spfa(int s,int u){ vis[u]=1; for(int i=head[u],v,w;i;i=e[i].nxt){ if(bl[v=e[i].v]!=bl[s]) continue; if(dis[s][v]>dis[s][u]+(w=e[i].w)){ dis[s][v]=dis[s][u]+w; if(vis[v]) return 1; if(spfa(s,v)) return 1; } } vis[u]=0; return 0; } int main(){ freopen("in.txt","r",stdin); rd(n),rd(m1),rd(m2); memset(dis,inf,sizeof(dis)); for(int i=1,x,y;i<=m1;++i) rd(x),rd(y),add(x,y,-1),add(y,x,1); for(int i=1,x,y;i<=m2;++i) rd(x),rd(y),add(x,y,0); for(int i=1;i<=n;++i){ if(!dfn[i]) tarjan(i); dis[i][i]=0; } for(int i=1;i<=n;++i){ memset(vis,0,sizeof(vis)); if(spfa(i,i)) return puts("NIE"),0; } for(int k=1;k<=Bcnt;++k){ int nw=0; for(int i=1;i<=n;++i){ if(bl[i]!=k) continue; for(int j=1;j<=n;++j) if(bl[j]==k) nw=Max(nw,dis[i][j]); } ans+=nw+1; } printf("%d",ans); return 0; }