建议评绿
查看原帖
建议评绿
658786
STUDENT00楼主2022/11/12 19:29

模板缩点,一丁点儿修改都不用!

#include<bits/stdc++.h>
using namespace std;
int n,m,p,t[3010],dfn[3010],low[3010],fa[3010],cnt,pa[3010],ans,tot;
bool vis[3010],vv[3010];
stack<int> st;
vector<int> w[3010];
void tarjan(int now){
	st.push(now);
	vis[now]=1;
	dfn[now]=low[now]=++cnt;
	for(int i=0;i<w[now].size();i++){
		int t=w[now][i];
		if(!dfn[t]){
			tarjan(t);
			low[now]=min(low[now],low[t]);
		}else if(vis[t]) low[now]=min(low[now],dfn[t]);
	}
	if(low[now]==dfn[now]){
		tot++;
		int y;
		do{
			y=st.top();
			st.pop();
			fa[y]=tot;
			vis[y]=0;
			if(t[y]!=-1) pa[tot]=min(pa[tot],t[y]);
		}while(now!=y);
	}
} 
int f(){
	vector<int> y[3010];
	for(int i=1;i<=n;i++) y[fa[i]].push_back(i);
	int mins=1e9;
	for(int i=1;i<=tot;i++){
		if(!vv[i]&&pa[i]==pa[0]){
			for(int j=0;j<y[i].size();j++) mins=min(mins,y[i][j]);
		}
	} 
	return mins;
}
int main(){
	memset(pa,127,sizeof(pa));
	memset(t,-1,sizeof(t));
	scanf("%d%d",&n,&p);
	while(p--){
		int a,b;
		scanf("%d%d",&a,&b);
		t[a]=b;
	}
	scanf("%d",&m);
	while(m--){
		int u,v;
		scanf("%d%d",&u,&v);
		w[u].push_back(v);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]) tarjan(i);
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<w[i].size();j++){
			int t=w[i][j];
			if(fa[i]!=fa[t]) vv[fa[t]]=1;
		}
	}
	for(int i=1;i<=tot;i++){
		if(!vv[i]){
			if(pa[i]==pa[0]){
				printf("NO\n%d",f());
				return 0;
			}else ans+=pa[i];
		}
	}
	printf("YES\n%d",ans);
	return 0;
}
2022/11/12 19:29
加载中...