这UKE好整人心态啊
  • 板块CF427C Checkposts
  • 楼主__2009
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/1/24 23:16
  • 上次更新2023/10/24 03:09:36
查看原帖
这UKE好整人心态啊
767748
__2009楼主2023/1/24 23:16

无论是思路还是写法我都觉得没问题啊!!!

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=1e7+5;
const int mod=1e9+7;
struct Edge{
    int to,nxt;
};
Edge edge[maxn],e[maxn];
int head1[maxn],cnt1=0;
int head2[maxn],cnt2=0;
int z1[maxn],z2[maxn];
void add(int u,int v,int _){
	if(_==1){
		edge[++cnt1].to=v;
	    edge[cnt1].nxt=head1[u];
    	head1[u]=cnt1;
	}
	else{
		e[++cnt2].to=v;
  	    e[cnt2].nxt=head2[u];
    	head2[u]=cnt2;
	}
    
}
int dfn[maxn],low[maxn],ts;
int stk[maxn],top;
bool instk[maxn];
int scc[maxn],sc;
int siz[maxn];
void tarjan(int u){
	dfn[u]=low[u]=++ts;
	stk[++top]=u;
	instk[u]=true;
	for(int i=head1[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(instk[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(dfn[u]==low[u]){
		sc++;
		while(true){
			int x=stk[top--];;
			scc[x]=sc;
			siz[sc]++;
			instk[x]=false;
			if(x==u)break;
		}
	}
}
int ans,_ans=1;
int cnt[maxn];
int main(){
	//输入 
	int n,m;
	cin>>n;
	int i;
	for(i=1;i<=n;i++)cin>>z1[i];
	cin>>m;
	int a,b;
	//加边 
	for(i=0;i<m;i++){
		scanf("%d%d",&a,&b);
		add(a,b,1);
	}
	//分出强连通分量 
	for(i=1;i<=n;i++){
		if(!dfn[i])tarjan(i);
	}
	//缩点 
	for(i=1;i<=sc;i++)z2[i]=0x3f3f3f3f;
	for(int u=1;u<=n;u++){
		for(i=head1[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(scc[u]!=scc[v])add(scc[u],scc[v],21541);//1~sc
		}
		z2[scc[u]]=min(z2[scc[u]],z1[u]);//点权 
	}
	//算每个强连通分量内最小价格的个数 
	for(int u=1;u<=n;u++){
		if(z2[scc[u]]==z1[u])cnt[scc[u]]++;
	}
	//处理答案 
	for(i=1;i<=sc;i++){
		ans+=z2[i];//最少价格 
		_ans*=cnt[i];//乘法原理 
		_ans%=mod;
	}
	printf("%d %d",ans,_ans);
	return 0;
}
2023/1/24 23:16
加载中...