tarjan缩点

之后跑一边spfa即可

  1 #include<cstdio>
  2 #include<cstring>
  3 using namespace std;
  4 const int N=500010,novis=-1,over=1,nowvis=0;
  5 int head1[N],head2[N],value[N],n,m,size,ans;
  6 int low[N],dfn[N],flag[N],que[N],sum[N],color[N],
  7     cnt,sig,top;
  8 int zh[N],vis[N],dis[N];
  9 struct fx{
 10     int to,next;
 11 }e1[N],e2[N];
 12 int min(int,int),max(int,int),read();
 13 void dfs(int),tarjan(),rebuild(),spfa(int);
 14 void uni2(int,int),uni(int,int);
 15 int main(){
 16     int x,y,p,tmp,s;
 17     memset(head1,0,sizeof(head1));
 18     size=ans=0;
 19     n=read();m=read();
 20     for (int i=1;i<=m;i++){
 21         x=read();y=read();
 22         uni(x,y);
 23     }
 24     for (int i=1;i<=n;i++)
 25         value[i]=read();
 26     s=read();p=read();
 27     tarjan();
 28     spfa(color[s]);
 29     for (int i=1;i<=p;i++){
 30         tmp=read();
 31         ans=max(ans,dis[color[tmp]]);
 32     }
 33     printf("%d",ans);
 34     return 0;
 35 }
 36 void uni(int x,int y){
 37     size++;
 38     e1[size].next=head1[x];
 39     head1[x]=size;
 40     e1[size].to=y;
 41 }
 42 void uni2(int x,int y){
 43     size++;
 44     e2[size].next=head2[x];
 45     head2[x]=size;
 46     e2[size].to=y;
 47 }
 48 void tarjan(){
 49     sig=cnt=top=0;
 50     memset(flag,novis,sizeof(flag));
 51     memset(color,0,sizeof(color));
 52     memset(sum,0,sizeof(sum));
 53     for (int i=1;i<=n;i++)
 54         if (flag[i]==novis) dfs(i);
 55     rebuild();
 56 }
 57 void dfs(int x){
 58     flag[x]=nowvis;
 59     low[x]=dfn[x]=++sig;
 60     que[++top]=x;
 61     for (int e=head1[x];e;e=e1[e].next){
 62         int v=e1[e].to;
 63         if (flag[v]==novis){
 64             dfs(v);
 65             low[x]=min(low[x],low[v]);
 66         }
 67         else if (flag[v]==nowvis)
 68             low[x]=min(low[x],dfn[v]);
 69     }
 70     if (low[x]==dfn[x]){
 71         cnt++;int t;
 72         do{
 73             t=que[top--];
 74             flag[t]=over;
 75             color[t]=cnt;
 76             sum[cnt]+=value[t];
 77         }while (t!=x);
 78     }
 79 }
 80 void rebuild(){
 81     int v;size=0;
 82     for (int u=1;u<=n;u++)
 83         for (int e=head1[u];e;e=e1[e].next){
 84             v=e1[e].to;
 85             if (color[u]!=color[v]) 
 86                 uni2(color[u],color[v]);
 87         }
 88 }
 89 void spfa(int st){
 90     int r,l,u,v;
 91     memset(vis,0,sizeof(vis));
 92     memset(dis,0,sizeof(dis));
 93     r=1;l=0; zh[l]=st; vis[st]=1;
 94     dis[st]=sum[st];
 95     while (l<=r){
 96         u=zh[l++];
 97         if (l==N) l=0;
 98         for (int e=head2[u];e;e=e2[e].next){
 99             v=e2[e].to;
100             if (dis[v]<dis[u]+sum[v]){
101                 dis[v]=dis[u]+sum[v];
102                 if (!vis[v]){
103                     vis[v]=1;zh[r++]=v;
104                     if (r==N) r=0;
105                 }   
106             }
107          }
108          vis[u]=0;
109     }
110 }
111 int min(int x,int y){
112     return x<y?x:y;
113 }
114 int max(int x,int y){
115     return x>y?x:y;
116 }
117 int read(){
118     int ss=0;char c;
119     c=getchar();
120     while (c<'0'||c>'9') c=getchar();
121     while (c>='0'&&c<='9'){
122         ss=ss*10+c-'0';c=getchar();
123     }
124     return ss;
125 }
STD

 

posted on 2016-09-15 17:13  Absolutezero  阅读(219)  评论(0编辑  收藏  举报