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的更多相关文章

  1. 图论(Tarjan缩点):BZOJ 1194: [HNOI2006]潘多拉的盒子

    1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 344  Solved: 181[Submit][Stat ...

  2. BZOJ 1194: [HNOI2006]潘多拉的盒子( BFS + tarjan + dp )

    O(S²)枚举2个诅咒机, 然后O(n²)BFS去判断. 构成一个有向图, tarjan缩点, 然后就是求DAG的最长路.. ------------------------------------- ...

  3. BZOJ 1194 [HNOI2006]潘多拉的盒子 (图论+拓扑排序+tarjan)

    题面:洛谷传送门 BZOJ传送门 标签里三个算法全都是提高组的,然而..这是一道神题 我们把这道题分为两个部分解决 1.找出所有咒语机两两之间的包含关系 2.求出咒语机的最长上升序列 我们假设咒语机$ ...

  4. BZOJ 1194: [HNOI2006]潘多拉的盒子 [DP DFA]

    传送门 题意: s个DFA,选出尽量多的自动机a0, a1, a2, . . . , at,使得a1包含a0.a2包 含a1,以此类推.s ≤ 50. DFA的字符集为{0,1},有的节点是输出源,节 ...

  5. 潘多拉的盒子(bzoj 1194)

    Description Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的格 ...

  6. 1194: [HNOI2006]潘多拉的盒子 - BZOJ

    Description  Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的 ...

  7. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  8. BZOJ 2693: jzptab [莫比乌斯反演 线性筛]

    2693: jzptab Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1194  Solved: 455[Submit][Status][Discu ...

  9. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

随机推荐

  1. 《SDN核心技术剖析和实战指南》2.1交换机核心技术小结

    对于SDN交换机的技术,其实也适用于传统的交换机,只不过控制部分被分离出来而已.传统交换机的控制面主要是转发表的管理以及网络状态之类的各种表,现在这些都由控制器来担心.转发面主要由转发决策.背板和输出 ...

  2. 40 个重要的 HTML5 面试问题及答案

    本文将列出40个重要的HTML 5面试问题及答案,祝各位求职顺利. 目录 介绍 Canvas和SVG图形之间的区别是什么? 如何使用Canvas和SVG绘制矩形? 什么是CSS选择器? 如何使用ID值 ...

  3. ORACLE归档模式和非归档模式的利与弊

    转: 在Oracle数据库中,主要有两种日志操作模式,分别为非归档模式与归档模式.默认情况下,数据库采用的是非归档模式.作为一个合格的数据库管理员,应当深入了解这两种日志操作模式的特点,并且在数据库建 ...

  4. 有关UITableViewCell的侧滑删除以及使用相关大神框架MGSwipeTableCell遇到的小问题

    提起笔,却不知道从何写起了,今天一整天都耗费在了这个可能根本不算是问题的小问题上,至今仍有一种蛋蛋的忧桑..(噢,不是提笔,是键盘手T_T) 表格视图在项目中就像是每日的家常便饭,在cell上添加侧滑 ...

  5. 用java实现Simsimi小黄鸡接口

    package com.iask.webchat.chatmachine; import java.io.BufferedReader; import java.io.InputStream; imp ...

  6. android手机内存大小获取

    //获取手机中文件管理器中存储大小 File datadir = Environment.getExternalStorageDirectory(); //获取手机内部的存储大小 File datad ...

  7. MySQL数据库的双向加密方式

    如果你正在运行使用MySQL的Web应用程序,那么你把密码或者其他敏感信息保存在应用程序里的机会就很大.保护这些数据免受或者窥探者的获取 是一个令人关注的重要问题,因为您既不能让未经授权的人员使用或者 ...

  8. J2EE (十) 简洁的JSTL、EL

    简介 JSTL(JSP Standard Tag Library ,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库. 由四个定制标记库(core.format.xml 和 sql)和一对通 ...

  9. 对return 语句的正确性和效率进行检查

    注意事项如下: 1. return 语句不可返回指向"堆栈内存“的”指针“或者”引用“,因为该内存单元在函数体结束时被自动释放. //错误 char* Func(void) { char s ...

  10. 关于获得本机Mac Address的方法

    网络上有讲获得Mac address的方法有如下: 1. 发送ARP命令,利用返回的Mac Address缓冲区得到 2. 用NetworkInterface.GetAllNetworkInterfa ...