bzoj 1194
http://www.lydsy.com/JudgeOnline/problem.php?id=1194
我们看看怎么判断B是否是A的升级。
我们新建一个图G,每个点为一个二元组(i,j),表示A的i号点和B的j号点。
设A中i号点的0出边为p0[i],B中j号点的0出边为p0[j],那么在图G中(i,j)连一条有向边到(p0[i],p0[j])
同理,设A中i号点的1出边为p1[i],B中j号点的1出边为p1[j],那么在图G中(i,j)连一条有向边到(p1[i],p1[j])
我们在图G中从(0,0)点开始BFS,如果到了某个点(i,j),在A中i号是输出点,但是在B中j号点不是输出点,那么B不是A的升级。
如果没出现上面那种情况,那么B是A的升级。
现在已知道了各个咒语机的升级关系了。
如果B是A的升级,那么连有向边A->B。
我们要在这个有向图中找一条最长路径。
先缩点,变成有向无环图,然后拓扑排序。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b) for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define SF scanf
#define PF printf
#define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-;
inline int sgn(DB x){if(abs(x)<EPS)return ;return(x>)?:-;}
const DB Pi=acos(-1.0); inline int gint()
{
int res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
}
inline LL gll()
{
LL res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
} const int maxN=; int S;
struct Tdata
{
int N,M,flag[maxN+],p[maxN+][];
inline void input()
{
int i;
N=gint();M=gint();
mmst(flag,);
re(i,,M)flag[gint()+]=;
re(i,,N)p[i][]=gint()+,p[i][]=gint()+;
}
}data[maxN+]; int vis[maxN+][maxN+];
int head,tail;
PII que[maxN*maxN+];
inline int check(int a,int b)
{
mmst(vis,);
que[head=tail=]=PII(,);
vis[][]=;
if(data[a].flag[] && !data[b].flag[])return ;
while(head<=tail)
{
int i,x=que[head].fi,y=que[head].se;head++;
re(i,,)
{
int tx=data[a].p[x][i],ty=data[b].p[y][i];
if(vis[tx][ty])continue;
vis[tx][ty]=;
que[++tail]=PII(tx,ty);
if(data[a].flag[tx] && !data[b].flag[ty])return ;
}
}
return ;
} int now,first[maxN+];
struct Tedge{int v,next;}edge[maxN*maxN+];
inline void addedge(int u,int v){now++;edge[now].v=v;edge[now].next=first[u];first[u]=now;}
int tot,idx[maxN+],val[maxN+],f[maxN+],form[maxN+],ans;
vector<int> G[maxN+]; int cnt,low[maxN+],dfn[maxN+],vis2[maxN+];
int top,sta[maxN+];
inline void Tarjan(int u)
{
dfn[u]=low[u]=++cnt;
vis2[sta[++top]=u]=;
int i,v;
for(i=first[u],v=edge[i].v;i!=-;i=edge[i].next,v=edge[i].v)
if(!vis2[v])
{
Tarjan(v);
upmin(low[u],low[v]);
}
else
if(vis2[v]==) upmin(low[u],dfn[v]);
if(low[u]==dfn[u])
{
++tot;
while()
{
idx[sta[top]]=tot;
val[tot]++;
G[tot].push_back(sta[top]);
vis2[sta[top]]=;
top--;
if(sta[top+]==u)break;
}
}
} int du[maxN+];
int ge,h[maxN+];
Tedge t[maxN*maxN+];
inline void addedge2(int u,int v){ge++;t[ge].v=v;t[ge].next=h[u];h[u]=ge;} int Q[maxN+]; int ds,out[maxN+]; int main()
{
/*freopen("bzoj1194.in","r",stdin);
freopen("bzoj1194.out","w",stdout);*/
int i,j;
S=gint();
re(i,,S)data[i].input();
mmst(first,-);now=-;
re(i,,S)re(j,,S)if(i!=j && check(i,j))addedge(i,j);/*,PF("%d->%d\n",i,j);*/
re(i,,S)if(!vis2[i])Tarjan(i);
ge=-;mmst(h,-);
int u,v;
re(u,,S)for(i=first[u],v=edge[i].v;i!=-;i=edge[i].next,v=edge[i].v)if(idx[u]!=idx[v])addedge2(idx[u],idx[v]),du[idx[v]]++;
head=;tail=-;
re(i,,tot)if(du[i]==)Q[++tail]=i,f[i]=val[i],form[i]=;
while(head<=tail)
{
int u=Q[head++],v;
for(i=h[u],v=t[i].v;i!=-;i=t[i].next,v=t[i].v)
{
if(val[v]+f[u]>f[v])f[v]=val[v]+f[u],form[v]=u;
du[v]--;
if(du[v]==)Q[++tail]=v;
}
}
int p;
ans=;
re(i,,tot)if(f[i]>ans)ans=f[i],p=i;
cout<<ans<<endl;
/*while(p)out[++ds]=p,p=form[p];
red(i,ds,1)re(j,0,int(G[out[i]].size())-1)PF("%d ",G[out[i]][j]-1);PF("\n");*/
return ;
}
bzoj 1194的更多相关文章
- 图论(Tarjan缩点):BZOJ 1194: [HNOI2006]潘多拉的盒子
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 344 Solved: 181[Submit][Stat ...
- BZOJ 1194: [HNOI2006]潘多拉的盒子( BFS + tarjan + dp )
O(S²)枚举2个诅咒机, 然后O(n²)BFS去判断. 构成一个有向图, tarjan缩点, 然后就是求DAG的最长路.. ------------------------------------- ...
- BZOJ 1194 [HNOI2006]潘多拉的盒子 (图论+拓扑排序+tarjan)
题面:洛谷传送门 BZOJ传送门 标签里三个算法全都是提高组的,然而..这是一道神题 我们把这道题分为两个部分解决 1.找出所有咒语机两两之间的包含关系 2.求出咒语机的最长上升序列 我们假设咒语机$ ...
- BZOJ 1194: [HNOI2006]潘多拉的盒子 [DP DFA]
传送门 题意: s个DFA,选出尽量多的自动机a0, a1, a2, . . . , at,使得a1包含a0.a2包 含a1,以此类推.s ≤ 50. DFA的字符集为{0,1},有的节点是输出源,节 ...
- 潘多拉的盒子(bzoj 1194)
Description Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的格 ...
- 1194: [HNOI2006]潘多拉的盒子 - BZOJ
Description Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的 ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 2693: jzptab [莫比乌斯反演 线性筛]
2693: jzptab Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1194 Solved: 455[Submit][Status][Discu ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
随机推荐
- mysql优化整理(索引)
什么是索引? 索引是表记录的单个或多个字段重新组织的一种方法,其目的是提高数据库的查询速度,本质上就是一种数据结构. 索引的类型:primary(主键).secondary(其他) 索引的数据结构 I ...
- <WinForm_1>初识WinForm编程
暑假花了一个多月自学了Win32 SDK编程,不敢说成为了高手,但是还是颇具收获——windows的消息机制(著名的消息循环).一切控件均是窗口…… 曾经有一位网友(和我一个专业的)向我吐槽:Win3 ...
- C# 文件上传
一.分析 本次博客,主要解决文件上传等一系列问题,将从两方面来论述,即1G以内文件和1G以上文件. 对于上传1G以内的文件,可以采用基本的三种上传方法:用Web控件FileUpload.html控件 ...
- SQL 查询某字段id为空(不为空)
1 sql 查询某字段id为空 select * from 表名 where id is null ; 2 sql 查询某字段id不为空 select * from 表名 wher ...
- 获取当前位置信息-ios
locationManager= [[CLLocationManager alloc] init];//位置管理器 locationManager.desiredAccuracy = kCLLocat ...
- 【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色、光照与材质
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨) ...
- 苹果的HomeKit协议
苹果的HomeKit协议非常底层,其作用仅限于让iOS平台和家居设备能够相互“握手”,但“认识”之后,想要继续控制灯.空调等设备,仍然需要家电厂商在HomeKit的基础上进行二次开发.
- 大数据笔记09:大数据之Hadoop的HDFS使用
1. HDFS使用: HDFS内部中提供了Shell接口,所以我们可以以命令行的形式操作HDFS
- mysql数据库的高可用方法总结
高可用架构对于互联网服务基本是标配,无论是应用服务还是数据库服务都需要做到高可用.虽然互联网服务号称7*24小时不间断服务,但多多少少有一 些时候服务不可用,比如某些时候网页打不开,百度不能搜索或者无 ...
- ubuntu 安装RPM软件包
red hat 系统用rpm格式的文件安装软件,ubuntu安装软件是用deb格式的文件安装 在ubuntu上安装rmp文件格式的软件包步骤: 1.安装转换软件 alien(需要联网) apt-get ...