最短路树。。。开眼界了。。。之前想也没想过。。。。
先跑出来1到每个点最短路,然后建树时要标记点的入度,否则会多连边。。。然后深搜时更新新答案就是
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #define R register int #define mp make_pair const int N=10010,M=50010; using namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int n,m,t,cnt; int vr[M<<1],nxt[M<<1],w[M<<1],fir[N]; long long sz[N],d[N],ans,c[N]; bool vis[N]; inline void add(int u,int v,int ww) {vr[++cnt]=v,w[cnt]=ww,nxt[cnt]=fir[u],fir[u]=cnt;} int vv[M<<1],nn[M<<1],ww[M<<1],ff[N]; inline void aadd(int u,int v,int w) {vv[++cnt]=v,ww[cnt]=w,nn[cnt]=ff[u],ff[u]=cnt;} priority_queue<pair<long long,int> > q; inline void dijk() { memset(d,0x3f,sizeof(long long)*(n+2)); d[1]=0; q.push(mp(0,1)); while(q.size()) { R u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=true; for(R i=fir[u];i;i=nxt[i]) { R v=vr[i]; if(d[v]>d[u]+w[i]) d[v]=d[u]+w[i],q.push(mp(-d[v],v)); } } } void dfs(int u) { vis[u]=true; for(R i=ff[u];i;i=nn[i]) { R v=vv[i]; if(vis[v]) continue; dfs(v); sz[u]+=sz[v]; } ans=max(sz[u]*(d[u]-t),ans);//,cout<<u<<" "<<sz[u]<<" "<<d[u]<<" "<<t<<" "<<sz[u]*(d[u]-t)<<endl; } signed main() { n=g(),m=g(),t=g(); for(R i=1;i<=n;++i) sz[i]=g(); for(R i=1,u,v,w;i<=m;++i) u=g(),v=g(),w=g(),add(u,v,w),add(v,u,w); cnt=0; dijk(); memset(vis,false,sizeof(vis)); for(R u=1;u<=n;++u) for(R i=fir[u];i;i=nxt[i]) if(d[vr[i]]==d[u]+w[i]&&!vis[vr[i]]) vis[vr[i]]=true,aadd(u,vr[i],w[i]),aadd(vr[i],u,w[i]); memset(vis,false,sizeof(bool)*(n+2)); dfs(1); printf("%lld ",ans); }
2019.04.25