BZOJ P2788 「POI2012」Festival【Tarjan缩点】【floyd】

参见popoqqq大爷的题解orz
https://blog.csdn.net/popoqqq/article/details/48249845

#include <cmath>
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=1e3+5;
const ll Inf=1e18;

stack<ll>s;

ll n,m1,m2,ans,mp[N][N];
ll cnt,to[N*N],nxt[N*N],head[N];
ll tot,num,dfn[N],low[N],bel[N],vis[N];

inline ll read() {
    ll x=0;char ch=getchar();bool f=0;
    while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return f?-x:x;
}

void ins(ll x,ll y) {
	to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt;
}

void tarjan(ll x) {
	dfn[x]=low[x]=++num;vis[x]=1;s.push(x);
	for(ll i=head[x];i;i=nxt[i]) {
		ll y=to[i];
		if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
		else if(vis[y]) low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]!=low[x]) return ;
	
	tot++;
	
	while(true) {
		ll y=s.top();s.pop();
		vis[y]=0;bel[y]=tot;
		if(x==y) return ;
	}
}

int main() {
	n=read(),m1=read(),m2=read();
	
	rep(i,1,n) rep(j,1,n) mp[i][j]=Inf;
	
	rep(i,1,m1) {
		ll x=read(),y=read();
		ins(x,y),ins(y,x);
		mp[x][y]=min(mp[x][y],1ll);
		mp[y][x]=min(mp[y][x],-1ll);
	}
	
	rep(i,1,m2) {
		ll x=read(),y=read();
		ins(y,x);mp[y][x]=min(mp[y][x],0ll);
	}
	
	rep(i,1,n) mp[i][i]=0;
	
	rep(k,1,n) rep(i,1,n) rep(j,1,n) mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
	
	rep(i,1,n) if(mp[i][i]<0) {
		puts("NIE");return 0;
	}
	
	rep(i,1,n) if(!dfn[i]) tarjan(i);
	
	rep(i,1,tot) {
		ll sum=0;
		rep(j,1,n) if(bel[j]==i) rep(k,1,n) if(bel[k]==i) sum=max(sum,mp[j][k]);
		ans+=sum+1;
	} 
	
	printf("%lld",ans);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/82776952