zoukankan      html  css  js  c++  java
  • 图论(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

    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。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <queue>
      5 #include <stack>
      6 using namespace std;
      7 const int maxs=51;
      8 const int maxn=51;
      9 int G[maxs][maxn][2];
     10 int P[maxs][maxn],S,n,m;
     11 bool vis[maxn][maxn];
     12 int cnt,fir[maxs],nxt[maxs*maxs*2],to[maxs*maxs*2];
     13 void addedge(int a,int b){
     14     nxt[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;
     15 }
     16 struct Node{
     17     int x,y;
     18 };
     19 queue<Node>q;
     20 void Solve(int x,int y){
     21     bool a=true,b=true;
     22     memset(vis,false,sizeof(vis));
     23     q.push((Node){0,0});vis[0][0]=true;
     24     while(!q.empty()){
     25         Node p=q.front();q.pop();
     26         if(P[x][p.x]^P[y][p.y]){
     27             if(P[x][p.x])b=false;
     28             if(P[y][p.y])a=false;    
     29         }
     30         if(!vis[G[x][p.x][0]][G[y][p.y][0]]){
     31             vis[G[x][p.x][0]][G[y][p.y][0]]=true;
     32             q.push((Node){G[x][p.x][0],G[y][p.y][0]});
     33         }
     34         if(!vis[G[x][p.x][1]][G[y][p.y][1]]){
     35             vis[G[x][p.x][1]][G[y][p.y][1]]=true;
     36             q.push((Node){G[x][p.x][1],G[y][p.y][1]});
     37         }
     38     }
     39     if(a)addedge(y,x);
     40     if(b)addedge(x,y);
     41     return;    
     42 }
     43 int ID[maxs],low[maxs],tot;
     44 int cntot,ring[maxs],val[maxs],inst[maxs];
     45 stack<int>st;
     46 void Tarjan(int x){
     47     ID[x]=low[x]=++tot;inst[x]=true;st.push(x);
     48     for(int i=fir[x];i;i=nxt[i]){
     49         if(ID[to[i]]){
     50             if(inst[to[i]])    
     51                 low[x]=min(low[x],ID[to[i]]);
     52         }
     53         else{
     54             Tarjan(to[i]);
     55             low[x]=min(low[x],low[to[i]]);
     56         }
     57     }
     58     if(ID[x]==low[x]){
     59         while(true){
     60             int y=st.top();st.pop();inst[y]=false;
     61             ring[y]=cntot;val[cntot]++;
     62             if(y==x)break;
     63         }
     64         ++cntot;
     65     }
     66 }
     67 int ans,ansd;
     68 bool E[maxs][maxs];
     69 int path[maxs],ret[maxs];
     70 void DFS(int x,int v,int dep){
     71     bool flag=false;path[dep]=x;
     72     for(int i=0;i<cntot;i++)
     73         if(E[x][i]){
     74             flag=true;
     75             DFS(i,v+val[i],dep+1);
     76         }
     77     if(!flag&&v>=ans){
     78         ans=v;ansd=dep;
     79         memcpy(ret,path,sizeof(ret));
     80     }
     81     return;
     82 }
     83 int main(){
     84     //freopen("pandora.in","r",stdin);
     85     //freopen("pandora.out","w",stdout);
     86     scanf("%d",&S);
     87     for(int k=0;k<S;k++){
     88         scanf("%d%d",&n,&m);
     89         for(int i=0,x;i<m;i++){
     90             scanf("%d",&x);    
     91             P[k][x]=true;
     92         }
     93         for(int i=0;i<n;i++)
     94             scanf("%d%d",&G[k][i][0],&G[k][i][1]);    
     95     }
     96     for(int i=0;i<S;i++)
     97         for(int j=i+1;j<S;j++)
     98             Solve(i,j);
     99     
    100     for(int i=0;i<S;i++)
    101         if(!ID[i])
    102             Tarjan(i);
    103     
    104     for(int x=0;x<S;x++)
    105         for(int i=fir[x];i;i=nxt[i])
    106             if(ring[to[i]]!=ring[x])
    107                 E[ring[x]][ring[to[i]]]=true;    
    108 
    109     for(int i=0;i<cntot;i++)        
    110         DFS(i,val[i],1);
    111     printf("%d
    ",ans);
    112     for(int i=1;i<=ansd;i++){
    113         for(int j=0;j<S;j++)
    114         if(ring[j]==ret[i]){
    115             printf("%d ",j);
    116         }
    117     }
    118     printf("
    ");
    119 }    

     

    尽最大的努力,做最好的自己!
  • 相关阅读:
    从错误状态恢复虚拟机
    OpenStack手动从数据库中删除实例
    对于flat_interface与public_interface的理解
    2. 拓扑图
    Cinder相关命令收集
    Nova相关命令收集
    14. Launch an instance
    9. Add the Block Storage service
    8. Add the dashboard
    7. Add a networking service
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5382279.html
Copyright © 2011-2022 走看看