40分,找半天发现
if(bu!=bv){
newout[bu].push_back(bv);
newin[bv]++;
}
写成
if(bu!=bv){
newout[u].push_back(v);
newin[v]++;
}
建边出问题了,建了个寂寞
AC码:
#include<bits/stdc++.h>
#define oo 1000000000
#define N 100050
typedef long long ll;
using namespace std;
inline ll read()
{
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
ll n,m,inp[N];
/*--------------------------------------------------------------*/
//链式前向星
struct EDGE{
ll nex,to;
}edge[N];
ll head[N];//-1
ll ecnt=1;
void adde(ll u,ll v){
edge[ecnt].to=v;
edge[ecnt].nex=head[u];
head[u]=ecnt++;
}
/*--------------------------------------------------------------*/
ll low[N],dfn[N],ins[N],belong[N],newsum[N];
ll DFN=1;
stack<ll>esta;
vector<ll>gh[N];
ll newcnt=0;//新图节点数
//Targin缩点
void targin(ll u){
esta.push(u);//入栈
ins[u]=1;//标记在栈内
low[u]=dfn[u]=DFN++;
for(int i=head[u];i!=-1;i=edge[i].nex){//遍历u的所有边
ll v=edge[i].to;//边的终点
if(!dfn[v]){//未处理过
targin(v);//就深搜
low[u]=min(low[u],low[v]);//v刚搜过,用来更新
}else if(ins[v]){//处理过并且还在栈内
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){//保证递归在回到环起始点的时候再缩,防止缩欠了
newcnt++;
while(esta.size()){
ll temp=esta.top();
belong[temp]=newcnt;//归属
newsum[newcnt]+=inp[temp];
ins[temp]=0;//出栈
esta.pop();
if(temp==u){
break;
}
}
}
}
/*--------------------------------------------------------------*/
void init(){
for(int i=0;i<N;i++){
head[i]=-1;
}
}
/*--------------------------------------------------------------*/
//建新图
vector<ll>newout[N];
ll newin[N];
void creat(){
for(int u=1;u<=n;u++){
for(int i=head[u];i!=-1;i=edge[i].nex){
ll v=edge[i].to;
ll bu=belong[u];
ll bv=belong[v];
if(bu!=bv){
newout[bu].push_back(bv);
newin[bv]++;
}
}
}
}
/*--------------------------------------------------------------*/
ll dp[N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>inp[i];
}
init();
for(int i=1;i<=m;i++){
ll x,y;
cin>>x>>y;
adde(x,y);
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
targin(i);
}
}
creat();
queue<ll>Q;
for(int i=1;i<=newcnt;i++){
if(!newin[i]){
dp[i]=newsum[i];
Q.push(i);
}
}
while(Q.size()){
ll a=Q.front();
Q.pop();
for(auto p=newout[a].begin();p!=newout[a].end();p++){
dp[*p]=max(dp[*p],dp[a]+newsum[*p]);
newin[*p]--;
if(!newin[*p]){
Q.push(*p);
}
}
}
ll ans=0;
for(int i=1;i<=newcnt;i++){
ans=max(ans,dp[i]);
}
cout<<ans;
return 0;
}