[BZOJ1179] [Apio2009]Atm(强连通)
2018-02-13 10:56
405 查看
题意传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1179
由于一个环上的点一定可以全部拿到,所以可以考虑强连通缩点,缩点之后用连通块建新图,将有酒吧的连通块连到ed,跑一边最长路即可。
(初始化的位置一定要放对啊啊啊啊!!!
code:
由于一个环上的点一定可以全部拿到,所以可以考虑强连通缩点,缩点之后用连通块建新图,将有酒吧的连通块连到ed,跑一边最长路即可。
(初始化的位置一定要放对啊啊啊啊!!!
code:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int maxn=500010; struct node { int x,y,c,next; }a[maxn*2],b[maxn*2]; int len1,last1[maxn]; int len2,last2[maxn]; int n,m; void ins1(int x,int y) { len1++; a[len1].x=x;a[len1].y=y; a[len1].next=last1[x]; last1[x]=len1; } void ins2(int x,int y,int c) { len2++; b[len2].x=x;b[len2].y=y;b[len2].c=c; b[len2].next=last2[x]; last2[x]=len2; } int low[maxn],dfn[maxn],id; int sta[maxn],top; bool insta[maxn]; int bl[maxn],scc; int w[maxn],sum[maxn]; void dfs(int x) { dfn[x]=low[x]=++id; sta[++top]=x; insta[x]=true; for(int k=last1[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==-1) { dfs(y); low[x]=min(low[x],low[y]); } else { if(insta[y]) low[x]=min(low[x],dfn[y]); } } if(low[x]==dfn[x]) { int i; scc++; do{ i=sta[top--]; bl[i]=scc; insta[i]=false; sum[scc]+=w[i]; }while(i!=x); } } int st,ed,stt; bool ved[maxn]; void rebuild() { st=bl[stt]; for(int i=1;i<=len1;i++) { int x=a[i].x,y=a[i].y; if(bl[x]!=bl[y]) ins2(bl[x],bl[y],sum[bl[x]]); } for(int i=1;i<=n;i++) { if(ved[i]==true) { ins2(bl[i],ed,sum[bl[i]]); } } } int d[maxn]; int list[maxn*2],head,tail; bool vs[maxn]; void spfa() { memset(d,-1,sizeof(d)); d[st]=0; memset(vs,false,sizeof(vs)); vs[st]=true; head=1,tail=2; list[head]=st; while(head!=tail) { int x=list[head]; for(int k=last2[x];k;k=b[k].next) { int y=b[k].y; if(d[y]<d[x]+b[k].c) { d[y]=d[x]+b[k].c; if(vs[y]==false) { vs[y]=true; list[tail++]=y; } } } head++; vs[x]=false; } } void init() { id=top=scc=len1=len2=0; memset(dfn,-1,sizeof(dfn)); memset(low,0,sizeof(low)); memset(sta,0,sizeof(sta)); memset(bl,0,sizeof(bl)); memset(sum,0,sizeof(sum)); memset(last1,0,sizeof(last1)); memset(last2,0,sizeof(last2)); } int main() { init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); ins1(u,v); } for(int i=1;i<=n;i++) scanf("%d",&w[i]); int tt; scanf("%d%d",&stt,&tt); for(int ti=1;ti<=tt;ti++) { int x;scanf("%d",&x); ved[x]=true; } for(int i=1;i<=n;i++) if(dfn[i]==-1) dfs(i); ed=scc+1; rebuild(); spfa(); printf("%d\n",d[ed]); return 0; }
相关文章推荐
- [BZOJ1179]APIO2009 ATM |强联通分量|DP
- 【Apio2009】Bzoj1179 Atm
- 【bzoj1179】 Apio2009—Atm
- [BZOJ 1179][APIO 2009]Atm
- BZOJ1179 [Apio2009]Atm 【tarjan缩点】
- 【强连通分量+spfa】Bzoj1179 Apio2009 Atm
- 【BZOJ1179】[Apio2009]Atm (tarjan+SPFA)
- 【bzoj 1179】[Apio2009]Atm(Tarjan+spfa)
- BZOJ1179 [Apio2009]Atm 【tarjan缩点】
- 【BZOJ1179】【APIO2009】Atm(tarjan+spfa)
- BZOJ 1179 [Apio2009]Atm(强连通分量)
- bzoj1179: [Apio2009]Atm
- BZOJ1179 [Apio2009] Atm
- BZOJ 1179: [Apio2009]Atm( tarjan + 最短路 )
- 【bzoj1179】[Apio2009]Atm Tarjan缩点+Spfa最长路
- BZOJ1179 [Apio2009]Atm
- BZOJ_1179_[Apio2009]Atm_tarjan+spfa
- BZOJ 1179: [Apio2009]Atm
- bzoj 1179: [Apio2009]Atm tarjan
- 【BZOJ】1179: [Apio2009]Atm(tarjan+spfa)