1194: [HNOI2006]潘多拉的盒子

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 344  Solved: 181
[Submit][Status][Discuss]

Description

Input

第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50)。文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述。每一块的格式如下。 一块的第一行有两个正整数n,m。分别表示该咒语机中元件的个数、咒语源输出元的个数(1≤m≤n≤50)。 接下来一行有m个数,表示m个咒语源输出元的标号(都在0到n-1之间)。接下来有n行,每一行两个数。第i行(0≤i≤n-1)的两个数表示pi,0和pi,1(当然,都在0到n-1之间)。

Output

第一行有一个正整数t,表示最长升级序列的长度。

Sample Input

4
1 1
0
0 0
2 1
0
1 1
0 0
3 1
0
1 1
2 2
0 0
4 1
0
1 1
2 2
3 3
0 0

Sample Output

3

  原题要输出方案,可是这里没有SPJ。

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
using namespace std;
const int maxs=;
const int maxn=;
int G[maxs][maxn][];
int P[maxs][maxn],S,n,m;
bool vis[maxn][maxn];
int cnt,fir[maxs],nxt[maxs*maxs*],to[maxs*maxs*];
void addedge(int a,int b){
nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
}
struct Node{
int x,y;
};
queue<Node>q;
void Solve(int x,int y){
bool a=true,b=true;
memset(vis,false,sizeof(vis));
q.push((Node){,});vis[][]=true;
while(!q.empty()){
Node p=q.front();q.pop();
if(P[x][p.x]^P[y][p.y]){
if(P[x][p.x])b=false;
if(P[y][p.y])a=false;
}
if(!vis[G[x][p.x][]][G[y][p.y][]]){
vis[G[x][p.x][]][G[y][p.y][]]=true;
q.push((Node){G[x][p.x][],G[y][p.y][]});
}
if(!vis[G[x][p.x][]][G[y][p.y][]]){
vis[G[x][p.x][]][G[y][p.y][]]=true;
q.push((Node){G[x][p.x][],G[y][p.y][]});
}
}
if(a)addedge(y,x);
if(b)addedge(x,y);
return;
}
int ID[maxs],low[maxs],tot;
int cntot,ring[maxs],val[maxs],inst[maxs];
stack<int>st;
void Tarjan(int x){
ID[x]=low[x]=++tot;inst[x]=true;st.push(x);
for(int i=fir[x];i;i=nxt[i]){
if(ID[to[i]]){
if(inst[to[i]])
low[x]=min(low[x],ID[to[i]]);
}
else{
Tarjan(to[i]);
low[x]=min(low[x],low[to[i]]);
}
}
if(ID[x]==low[x]){
while(true){
int y=st.top();st.pop();inst[y]=false;
ring[y]=cntot;val[cntot]++;
if(y==x)break;
}
++cntot;
}
}
int ans,ansd;
bool E[maxs][maxs];
int path[maxs],ret[maxs];
void DFS(int x,int v,int dep){
bool flag=false;path[dep]=x;
for(int i=;i<cntot;i++)
if(E[x][i]){
flag=true;
DFS(i,v+val[i],dep+);
}
if(!flag&&v>=ans){
ans=v;ansd=dep;
memcpy(ret,path,sizeof(ret));
}
return;
}
int main(){
//freopen("pandora.in","r",stdin);
//freopen("pandora.out","w",stdout);
scanf("%d",&S);
for(int k=;k<S;k++){
scanf("%d%d",&n,&m);
for(int i=,x;i<m;i++){
scanf("%d",&x);
P[k][x]=true;
}
for(int i=;i<n;i++)
scanf("%d%d",&G[k][i][],&G[k][i][]);
}
for(int i=;i<S;i++)
for(int j=i+;j<S;j++)
Solve(i,j); for(int i=;i<S;i++)
if(!ID[i])
Tarjan(i); for(int x=;x<S;x++)
for(int i=fir[x];i;i=nxt[i])
if(ring[to[i]]!=ring[x])
E[ring[x]][ring[to[i]]]=true; for(int i=;i<cntot;i++)
DFS(i,val[i],);
printf("%d\n",ans);
for(int i=;i<=ansd;i++){
for(int j=;j<S;j++)
if(ring[j]==ret[i]){
printf("%d ",j);
}
}
printf("\n");
}

图论(Tarjan缩点):BZOJ 1194: [HNOI2006]潘多拉的盒子的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. BZOJ1194: [HNOI2006]潘多拉的盒子(tarjan)

    Description 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...

  7. Tarjan水题系列(3):HNOI2006 潘多拉的魔盒

    题目: 链接 大意: 盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数 思路: 有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述 此题 ...

  8. 【强连通分量】Bzoj1194 HNOI2006 潘多拉的盒子

    Description Sulotion 首先要对每对咒语机建图,判断机器a是否能生成所有机器b生成的 如果跑一个相同的串,最后结束的点b可输出a不可输出,判断就为否 大概就用这种思路,f[x][y] ...

  9. 【bzoj1194】 HNOI2006—潘多拉的盒子

    http://www.lydsy.com/JudgeOnline/problem.php?id=1194 (题目链接) 题意 给出S个自动机,如果一个自动机u的所有状态是另一个自动机v的状态的子集,那 ...

随机推荐

  1. abc - zx

    诛仙青云志 第26集    第25集 第24集    第23集    第22集   第21集    第20集    第19集  第18集    第17集    第16集   第15集     第14集 ...

  2. oracle 字符串切割成结果集方法

    oracle字符串切割几种方式 方法一: SELECT COLUMN_VALUE FROM TABLE(SYS.ODCIVARCHAR2LIST('1','2','3','4','5')); 方法二: ...

  3. JS实现一键复制功能

    var copyClick = function (d) { var Url2 = $(d).parent().parent().find("#copy_value"); Url2 ...

  4. node基础再现--module.exports 和exports

    实际上,最最基础的方法,最最原始的方法是module.exports,至于exports,是为了方便书写才出来的,应该说,module.exports 包含exports,所工作的范围更加的广泛! m ...

  5. MVC ViewEngine视图引擎解读及autofac的IOC运用实践

    MVC 三大特色  Model.View.Control ,这次咱们讲视图引擎ViewEngine 1.首先看看IViewEngine接口的定义 namespace System.Web.Mvc { ...

  6. HTML5 canvas createRadialGradient()放射状/圆形渐变

    定义和用法 createLinearGradient() 方法创建放射状/圆形渐变对象. 渐变可用于填充矩形.圆形.线条.文本等等. 提示:请使用该对象作为 strokeStyle 或 fillSty ...

  7. u盘复制提示文件过大

    应该有很多个朋友也遇到过同样的问题,就是我们的u盘的明明可用的空间还有很多,甚至一个空的16g的u盘,但从window等操作系统向u盘拷贝文件的时候,却不能容下诸如iso4g的镜像文件,难道是生产u盘 ...

  8. Express在windows IIS上部署详解

    最近公司在用Express+angularjs+wcf开发系统,让我在windows上部署系统,遇到不少问题,不过最后还是解决了,在IIS上部署系统, 首先windows需安装以下软件: 1.node ...

  9. 基于nodejs的消息中心

    参考:http://t42dw.iteye.com/blog/1767013

  10. 24种设计模式--工厂方法模式【Factory Method Pattern】

    女娲补天的故事大家都听说过吧,今天不说这个,说女娲创造人的故事,可不是“造人”的工作,这个词被现代人滥用了. 这个故事是说,女娲在补了天后,下到凡间一看,哇塞,风景太优美了,天空是湛蓝的,水是清澈的, ...