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. Appnium+python实现手势密码为什么总是报错

    最近一直在尝试Appnium实现Android手机自动化测试,一直一直卡在一个点上,那就是手势密码,因为所测应用的手势密码使用的不是单个的imageview实现的手势密码解锁窗,所以只能靠坐标点来定位 ...

  2. MySQL 遇到的问题:在服务里找不到自己的 MySQL,以及在命令行窗口中运行服务出现的问题。

    1.用数据库的时候在服务里找不到自己的 MySQL ,于是就想用命令行窗口去运行. ①.在开始里,键入 cmd ,打开命令行窗口. ②.输入:mysql -u root -p 回车,这时会提示请输入密 ...

  3. jquery $.each()用法

    今天看到一个新的each玩法即each作为jquery的函数(平时用的大概都是用的each方法)使用: $.each([ 52, 97 ], function( index, value ) { al ...

  4. Swift学习——A Swift Tour 函数

    Functions and Closures  函数和封闭性(闭包) Functions  函数的使用 Swift中的函数定义和OC中有明显的差别了,使用func定义函数,在括号里定义參数和类型,用 ...

  5. XMPP通讯开发-好友获取界面设计

    在XMPP通讯开发-服务器连接 中我们成功连接到服务器上面,然后进入到主界面,接下来就是获取好友列表,这里我们分段开发,首先就是界面的设计,这里仿照QQ好友界面,里面的数据先是用模拟的,下一章获取服务 ...

  6. sgu Flow construction

    Flow construction 题目: 给出N个节点M条水管,要求在满足上下界的情况下.满足起点最小的流量. 算法: 这是最小流????不知道.仅仅知道用求解上下界最大流的方法就过了. 做这题收获 ...

  7. C# Interface显式实现和隐式实现

    c#中对接口的实现方式有两种:隐式实现和显式实现,之前一直没仔细看过,今天查了些资料,在这里整理一下. 隐式实现的例子 interface IChinese { string Speak(); } p ...

  8. c - 每位数字尾部加空格

    /* input:一个4位整数. output:每位整数后紧跟一个空格的字符串. */ char * insert(char *s) { int len = strlen(s); * len + ); ...

  9. 使用idea将本地项目上传至github及clone

    一.上传 1.firl->settings 设置git 2.firl->settings 填写自己的登录名和密码,可以使用test测试是否连接成功 3. 就搞定了.github会自动建立一 ...

  10. 【warning】clang the linker unused

    这个问题是 我在写第一个 mac os 下的helloworld遇到的 就像是 大家写第一个java中的 helloworld 肯定也是要在命令窗口下进行操作 一样 为了让一些和我一样的刚入门的孩子学 ...