BZOJ1924 tarjan+拓扑序

来源:互联网 发布:python bloomfilter 编辑:程序博客网 时间:2024/06/06 18:29

先按题目要求连边 缩点之后建反向图按拓扑序转移
sum[u]=max{sum[v]+sz[u]};
ans=max{sum[i]}(i[1,n]);

#include<bits/stdc++.h>#define bug(x) cout<<(#x)<<" "<<(x)<<endl#define ll long long#define cal(x,y) (x-1)*c+yusing namespace std;const int N=1e5+5;const int M=1e6+5;inline int read(){    int 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,r,c,cnt,tot=1,zjq,ans,id,flag,top; int head[N],bel[N],sz[N],sum[N],in[N],dfn[N],low[N],q[N],fx[]={-1,-1,-1,1,1,1,0,0},fy[]={-1,0,1,-1,0,1,1,-1};bool vis[N];vector<int>vx[M],vy[M];map<ll,int>mp;queue<int>s;struct node{    int x,y,t;}a[N*2];struct Edge{    int v,nxt;}e[M*4];void add(int u,int v){    e[++tot].v=v,e[tot].nxt=head[u],head[u]=tot,in[v]+=flag;}void tarjan(int x){    dfn[x]=low[x]=++id;vis[x]=1;q[++top]=x;    for(int i=head[x];i;i=e[i].nxt){        int j=e[i].v;        if(!dfn[j]) tarjan(j),low[x]=min(low[x],low[j]);         else if(vis[j]) low[x]=min(low[x],dfn[j]);    }    if(low[x]==dfn[x]){        ++cnt;        do{//          cout<<q[top]<<" ";            vis[q[top]]=0;            bel[q[top]]=cnt;            ++sz[cnt];        }while(q[top--]!=x);//      cout<<endl;    }}void rebuild(){    flag=tot=1;memset(head,0,sizeof head);memset(e,0,sizeof e);    for(int p=1;p<=n;p++){        if(a[p].t==1){            for(int i=0;i<vx[a[p].x].size();i++)                if(bel[vx[a[p].x][i]]!=bel[p])                    add(bel[vx[a[p].x][i]],bel[p]);        }        if(a[p].t==2){            for(int i=0;i<vy[a[p].y].size();i++)                if(bel[vy[a[p].y][i]]!=bel[p])                    add(bel[vy[a[p].y][i]],bel[p]);        }        if(a[p].t==3)             for(int i=0;i<8;i++){            ll cx=a[p].x+fx[i],cy=a[p].y+fy[i];            if(cx>r||cx<=0||cy>c||cy<=0) continue;            ll tmp=(ll)cal(cx,cy);            if(mp.count(tmp)){                int tt=mp[tmp];                if(bel[p]!=bel[tt]) add(bel[tt],bel[p]);            }        }    }} void solve(){    for(int i=1;i<=cnt;i++) if(!in[i]) s.push(i),sum[i]=sz[i];    while(!s.empty()){        int x=s.front();s.pop();        for(int i=head[x];i;i=e[i].nxt){            int j=e[i].v;            sum[j]=max(sum[j],sz[j]+sum[x]);            --in[j];            if(!in[j]) s.push(j);        }    }    for(int i=1;i<=cnt;i++) ans=max(ans,(ll)sum[i]);    printf("%lld\n",ans);}int main(){#ifdef Devil_Gary    freopen("in.txt","r",stdin);#endif    n=read(),r=read(),c=read();    for(int i=1;i<=n;i++){        a[i].x=read(),a[i].y=read(),a[i].t=read();        mp[cal(a[i].x,a[i].y)]=i;        vx[a[i].x].push_back(i);        vy[a[i].y].push_back(i);    }    for(int p=1;p<=n;p++){        if(a[p].t==1){            for(int i=0;i<vx[a[p].x].size();i++)                 if(vx[a[p].x][i]!=p)                     add(p,vx[a[p].x][i]);        }        if(a[p].t==2){            for(int i=0;i<vy[a[p].y].size();i++)                if(vy[a[p].y][i]!=p)                     add(p,vy[a[p].y][i]);        }        if(a[p].t==3)            for(int i=0;i<8;i++){                ll cx=a[p].x+fx[i],cy=a[p].y+fy[i];                if(cx>r||cx<=0||cy>c||cy<=0) continue;                ll tmp=(ll)cal(cx,cy);                if(mp.count(tmp)) add(p,mp[tmp]);            }    }    for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);    rebuild();    solve();    return 0; }
阅读全文
0 0
原创粉丝点击