图论(Tarjan缩点):BZOJ 1194: [HNOI2006]潘多拉的盒子
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
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
原题要输出方案,可是这里没有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]潘多拉的盒子的更多相关文章
- 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},有的节点是输出源,节 ...
- 1194: [HNOI2006]潘多拉的盒子
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 464 Solved: 221[Submit][Stat ...
- 1194: [HNOI2006]潘多拉的盒子 - BZOJ
Description Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的 ...
- BZOJ1194: [HNOI2006]潘多拉的盒子(tarjan)
Description 传说中,有个神奇的潘多拉宝盒.如果谁能打开,便可以拥有幸福.财富.爱情.可是直到真的打开,才发现与之 相随的还有灾难.不幸.其实,在潘多拉制造这个宝盒的时候,设置了一些咒语来封 ...
- Tarjan水题系列(3):HNOI2006 潘多拉的魔盒
题目: 链接 大意: 盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数 思路: 有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述 此题 ...
- 【强连通分量】Bzoj1194 HNOI2006 潘多拉的盒子
Description Sulotion 首先要对每对咒语机建图,判断机器a是否能生成所有机器b生成的 如果跑一个相同的串,最后结束的点b可输出a不可输出,判断就为否 大概就用这种思路,f[x][y] ...
- 【bzoj1194】 HNOI2006—潘多拉的盒子
http://www.lydsy.com/JudgeOnline/problem.php?id=1194 (题目链接) 题意 给出S个自动机,如果一个自动机u的所有状态是另一个自动机v的状态的子集,那 ...
随机推荐
- C++ 进阶必备
C++ 进阶要点(原理+熟练使用) 持续更新中 虚函数 虚继承 多继承 构造函数,拷贝构造函数,赋值构造函数,友元类,浅拷贝,深拷贝,运算符重载 class 类的基本使用,iostream获取屏幕输入 ...
- Unity3D GUI之自定义风格组件
GUI中可以使用一些默认的组件,里面的最后一个参数一般情况下,不设置就是默认的 ,当然也可以进行手动的指定,比如: GUI.Button(new Rect(0,0,100,100),"开始游 ...
- 使用JavaScriptSerializer序列化集合、字典、数组、DataTable为JSON字符串 分类: 前端 数据格式 JSON 2014-10-30 14:08 169人阅读 评论(0) 收藏
一.JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大 ...
- openwrt advanced configuration
openwrt高级配置(汗 照着标题就翻译过来了) openwrt Kamikaze 8.09的一般配置文件都在目录 /etc/config 下面,可以使用脚本来调用参数和设置参数. 比如 sbin/ ...
- mysql出现的错误
(一)ERROR 1005 (HY000): Can't create table '.\day19\user_role.frm' (errno: 121) 今天遇到的这个问题是因为创建了五张表,其中 ...
- 【原创】Git版本控制器的基本使用
关于git Git,是一个分布式版本控制软件.最初本是为了更好的管理Linux内核开发而被林纳斯·托瓦兹开发,后来因为项目开发中版本控制的强烈需求,而git也日趋成熟,最终成为了一个独立的版本控制软件 ...
- 【原】iOS 获取当前和 前后n天的日期
原文:http://www.cnblogs.com/A--G/p/4759810.html 一.获取当前日期需要调用一个简单的方法:[NSDate date];//获取现在的日期 -(NSString ...
- AspNetPage 使用案例
.首先在DBHelper创建一个方法,用于执行存储过程 public static DataTable ExecuteProc(string sql,params SqlParameter[] par ...
- 用JS实现版面拖拽效果
类似于这样的一个版面,点击标题栏,实现拖拽效果. 添加onmousedown事件 通过获取鼠标的坐标(clientX,clientY)来改变面板的位置 注意:面板使用绝对定位方式,是以左上角为参考点, ...
- 关于JavaScript的类的继承
其实最一开始学JS的时候就看过继承的实现.当时只是去试着理解从书上看来的代码段而已.今天又重新思考了一下,感觉这是一个思维探索演进的结果. 继承,即复用. 如果抛开继承的固有思想,让b复用a的成员,最 ...