社区讨论
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 条回复,欢迎继续交流。
正在加载回复...