社区讨论

Tarjan30pts求助

P2656采蘑菇参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo7tfw03
此快照首次捕获于
2023/10/27 07:28
2 年前
此快照最后确认于
2023/10/27 07:28
2 年前
查看原帖
Rt,Tarjan缩点30分……答案比标准输出略大一点
CPP
#include<bits/stdc++.h> 
using namespace std;
const int N=80010;
const int M=200010; 
int n,m,S,dfncnt;
int sc_num[N],dfn[N],low[N],sc[N],scccnt,ans;
bool vis[N],ins[N];
struct node{
	int v,num,maxn;
}t;
vector<node>E[N];
vector<node>F[N];
stack<int>s;
int Count(int n,long double k){
	int ans=0;
	while(n){
		ans+=n;
		n*=k;
	}
	return ans;
}
void dfs(int u){
	vis[u]=1;
	low[u]=dfn[u]=++dfncnt;
	s.push(u);ins[u]=1;//入栈 
	for(auto i:E[u]){
		if(!vis[i.v]){
			dfs(i.v);
			low[u]=min(low[u],low[i.v]);
		}
		else if(ins[i.v])low[u]=min(low[u],dfn[i.v]);
	}
	if(low[u]==dfn[u]){//u是根 
		scccnt++;
		sc[u]=scccnt;
		while(s.top()!=u){//s里的u上方点属于一个强连通分量 
			int dot=s.top();s.pop();
			sc[dot]=scccnt;ins[dot]=0;
		}s.pop();//u out
	}
}
void ser(int u,int num){
	ans=max(ans,num);
	if(F[u].size()==0)return ;
	for(auto i:F[u]){
		ser(i.v,num+i.num+sc_num[i.v]);
	}
}
int main(){
	//freopen("1.in","r",stdin);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u;long double k;
		cin>>u>>t.v>>t.num>>k;
		t.maxn=Count(t.num,k);
		E[u].push_back(t);
	}
	cin>>S;
	dfs(S);
	//------------------------------------
	//for(int i=1;i<=n;i++)cout<<dfn[i]<<' '<<low[i]<<' '<<sc[i]<<'\n';
	//return 0;
	//------------------------------------
	for(int i=1;i<=n;i++){//缩点 
		if(sc[i]==0)continue;
		for(auto j:E[i]){
			if(sc[i]==sc[j.v]){
				sc_num[sc[i]]+=j.maxn;//同分量加 
			}
			else{
				t.v=sc[j.v];
				t.num=j.num;
				F[sc[i]].push_back(t);//异分量只能采一次 
			}
		}
	}
	ser(sc[S],sc_num[sc[S]]);//找路 
	cout<<ans;
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...