省选专练SDOI2010所驼门王的宝藏
来源:互联网 发布:2016网络小说知乎50 编辑:程序博客网 时间:2024/05/18 02:19
这是一个奇怪的题
首先,其思路和APIO2009-3掠夺计划相比难得多,数据变大了啊。
于是两两建边不可行,考虑用拉链判重。
从横天门或纵寰门引出的边可能特别多。在极端情况下,10^5个横天门在同一行里出现,这样时空复杂度都是无法承受的。考虑这一点进行优化:由于在同一行的横天门一定属于同一个强连通分量,所以在建边时,只需要对在同一行的横天门构建出一个环即可,不需要两两进行连边。而此行内的其他宫室,只需要从这个环中的任意一点向这个宫室连边即可。对于纵寰门也是一样。
然后缩了点想干嘛就干嘛top还是SPFA都可以
#include<iostream>#include<cstdio>#include<stack>#include<algorithm>#include<cmath>#include<cstring>#include<queue>#include<map>using namespace std;inline void read(int &x){ int f=1; x=0; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch<='9'&&ch>='0'){ x=x*10+ch-'0'; ch=getchar(); } x*=f;}int dx[]={0,1,0,-1,1,1,-1,-1};int dy[]={1,0,-1,0,-1,1,-1,1};int n,r,c;struct Front_star{ int u,v,w,nxt;}edge[5000000],e[5000000],ee[5000000];int cnt=0;int first[500000]={0};int head[500000]={0};struct Node{ int x,y,t;}pre[2000007]/*first array*/,nxt[2000007],a[2000007];void addedge(int u,int v,int w){ cnt++; e[cnt].u=u; e[cnt].v=v; e[cnt].w=w; e[cnt].nxt=first[u]; first[u]=cnt;}void adde(int u,int v,int w){ cnt++; ee[cnt].u=u; ee[cnt].v=v; ee[cnt].w=w; ee[cnt].nxt=head[u]; head[u]=cnt;}void add(){ for(int i=1;i<=n;i++){ if(a[i].t==1){ for(int j=pre[a[i].x].x;j;j=nxt[j].x){ if(i==j){ continue; } addedge(i,j,1); } } if(a[i].t==2){ for(int j=pre[a[i].y].y;j;j=nxt[j].y){ if(i==j){ continue; } addedge(i,j,1); } } if(a[i].t==3){ for(int k=0;k<8;k++){ int xx=a[i].x+dx[k]; for(int j=pre[xx].x;j;j=nxt[j].x){ if(i==j) continue; if(abs(a[j].y-a[i].y)<=1) addedge(i,j,1); } } } }}int tot=0;//--------------int low[500000]={0};int dfn[500000]={0};int color[500000]={0};int siz[500000]={0};int inqueue[500000]={0};int scc=0;stack<int> S;void tarjan(int u){ tot++; low[u]=dfn[u]=tot; S.push(u); inqueue[u]=1; for(int i=first[u];i;i=e[i].nxt){ int v=e[i].v; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else{ if(inqueue[v]){ low[u]=min(low[u],dfn[v]); } } } if(low[u]==dfn[u]){ int x; scc++; do{ x=S.top(); S.pop(); color[x]=scc; siz[scc]++; inqueue[x]=0; }while(x!=u); }}int rd[500001]={0};int cd[500001]={0};int dis[500001]={0};void SPFA(){ queue<int>q; for(int i=1;i<=scc;i++){ if(rd[i]==0){ q.push(i); dis[i]=siz[i]; } } while(!q.empty()){ int x=q.front(); q.pop(); for(int i=head[x];i;i=ee[i].nxt){ int v=ee[i].v; if(rd[v]==0) continue; rd[v]--; if(dis[v]<dis[x]+siz[v]){ dis[v]=dis[x]+siz[v]; } if(!rd[v]){ q.push(v); } } }}int main(){ read(n); read(r); read(c); for(int i=1;i<=n;i++){ int x,y,t; read(x); read(y); read(t); a[i].x=x; a[i].y=y; a[i].t=t; nxt[i].x=pre[x].x; pre[x].x=i; nxt[i].y=pre[y].y; pre[y].y=i; } add(); for(int i=1;i<=n;i++){ if(!dfn[i]){ tarjan(i); } }//cnt=0;//memset(first,0,sizeof(first)); for(int i=1;i<=n;i++){ for(int j=first[i];j;j=e[j].nxt){ int v=e[j].v; int u=i; if(color[u]!=color[v]){ adde(color[u],color[v],1); rd[color[v]]++; cd[color[u]]++; } } }//for(int i=1;i<=scc;i++)//cout<<rd[i]<<" "<<siz[i]<<endl; SPFA(); int ans=-1;//cout<<"4q382436939486724389279834"<<endl; for(int i=1;i<=scc;i++){ ans=max(ans,dis[i]);//cout<<siz[i]<<" "<<cd[i]<<endl; } cout<<ans;}
阅读全文
0 0
- 省选专练SDOI2010所驼门王的宝藏
- 【SDOI2010】【BZOJ1924】所驼门王的宝藏
- 1924: [Sdoi2010]所驼门王的宝藏
- BZOJ1924: [Sdoi2010]所驼门王的宝藏
- BZOJ1924: [Sdoi2010]所驼门王的宝藏
- bzoj1924 [Sdoi2010]所驼门王的宝藏
- bzoj1924: [Sdoi2010]所驼门王的宝藏
- 1924: [Sdoi2010]所驼门王的宝藏
- 【BZOJ1924】【SDOI2010】所驼门王的宝藏
- 【bzoj1924】【SDOI2010】所驼门王的宝藏
- [BZOJ1924][SDOI2010]所驼门王的宝藏(Tarjan+拓扑排序)
- 【bzoj1924】[Sdoi2010]所驼门王的宝藏(tarjan+STL+dp)
- [BZOJ]1924: [Sdoi2010]所驼门王的宝藏 强连通+DP
- [SDOI2010]所驼门王的宝藏 --tarjan缩点+最长路
- BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP
- 1924: [Sdoi2010]所驼门王的宝藏 tarjan缩点+dp最长路
- bzoj 1924: [Sdoi2010]所驼门王的宝藏 (tarjan缩点+spfa)
- [SDOI2010]BZOJ 1924所驼门王的宝藏-强连通分量-缩点-拓扑排序-dp
- Configure Eclipse for stm32
- Spring data jpa多表查多条件查询
- sefsfsf
- 杂记
- 进程与线程,信号量与互斥量的区别
- 省选专练SDOI2010所驼门王的宝藏
- 关于Java script 定时器(timer)的一些使用
- 学习记录6
- spfa和广度优先遍历
- 12月9日的学习报告--定时器
- 集群部署时,session缓存问题
- okhttp3简单封装GET和POST请求工具类
- NFS服务的配置与应用
- 最小生成树模版题Prim——修建道路