zoukankan      html  css  js  c++  java
  • bjoi 2009 函数依赖 强连通分量

    对于30%的测试数据,满足只有二元联系(即不存在函数依赖左边或右边的
    属性个数超过 1 个)。 
    对于 40%的测试数据,满足N ≤ 5。 
    对于 70%的测试数据,满足M ≤ 100。 
    对于100%的测试数据,满足 1 ≤ N ≤ 10, 1 ≤ M ≤ 1000。

     

    思路:因为n非常小

    我们可以把2^n个关系全部列出来

    按照题目的关系建立有向图

    求强连通分量 缩点 拓扑排序

    答案就是 某个节点自己在头节点中,而他的真子集都不在

     

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 using namespace std;
      7 #define MAXN (1<<10)+1
      8 #define MAXM 1<<22
      9 struct node
     10 {
     11     int num;
     12     node *next;
     13 };
     14 node *graph[MAXN],*grapht[MAXN],*graphnew[MAXN];
     15 node memo[MAXM];
     16 bool use[MAXN],visit[MAXN][MAXN];
     17 int finish[MAXN],cnt[MAXN],mark[MAXN],ans[MAXN];
     18 int n,m,top=0,t=0,sum=0,color=0;
     19 pair<int,int> a[MAXN];
     20 char c[30];
     21 bool cmp(int x,int y)
     22 {
     23     for(int i=0;i<11;i++)
     24     {
     25         if(((1<<i)&x)==(1<<i)&&((1<<i)&y)!=(1<<i))
     26             return 1;
     27         if(((1<<i)&x)!=(1<<i)&&((1<<i)&y)==(1<<i))
     28             return 0;
     29     }
     30 
     31 }
     32 void add(int x,int y,node *graph[])
     33 {
     34     node *p=&memo[top++];
     35     p->num=y; p->next=graph[x]; graph[x]=p;
     36 }
     37 void dfs(int i)
     38 {
     39     use[i]=1;
     40     for(node *p=graph[i];p;p=p->next)
     41         if(!use[p->num])
     42             dfs(p->num);
     43     finish[++t]=i;
     44 }
     45 void dfst(int i)
     46 {
     47     use[i]=1;
     48     mark[i]=color;
     49     cnt[color]++;
     50     for(node *p=grapht[i];p;p=p->next)
     51         if(!use[p->num])
     52             dfst(p->num);
     53 }
     54 
     55 void connect()
     56 {
     57     memset(use,0,sizeof(use));
     58     int i;
     59     for(i=1;i<n;i++)
     60         if(!use[i])
     61             dfs(i);
     62     memset(use,0,sizeof(use));
     63     for(i=t;i>0;i--)
     64     if(!use[finish[i]])
     65     {
     66         color++;
     67         dfst(finish[i]);
     68     }
     69 }
     70 void reduce()
     71 {
     72     memset(visit,0,sizeof(visit));
     73     int i;
     74     for(i=1;i<n;i++)
     75     for(node *p=graph[i];p;p=p->next)
     76     {
     77         if(visit[mark[i]][mark[p->num]]==0&&mark[i]!=mark[p->num])
     78         {
     79             visit[mark[i]][mark[p->num]]=1;
     80             add(mark[i],mark[p->num],graphnew);
     81         }
     82     }
     83 }
     84 void solve()
     85 {
     86     t=0;
     87     memset(ans,0,sizeof(ans));
     88     memset(use,0,sizeof(use));
     89     int i,j,k;
     90     for(i=1;i<n;i++)
     91     if(mark[i]==1)
     92     {
     93         for(j=1;j<n;j++)
     94             if((i&j)==j&&mark[j]==1&&i!=j)
     95                 break;
     96         if(j==n) 
     97             ans[++t]=i;
     98     }
     99     printf("%d\n",t);
    100     sort(ans+1,ans+t+1,cmp);
    101     for(i=1;i<=t;i++)
    102     {
    103         for(j=0;j<11;j++)
    104             if((ans[i]&(1<<j))==(1<<j))
    105                 printf("%c",('A'+j));
    106         printf("\n");
    107     }
    108 }
    109 
    110 int main()
    111 {
    112     memset(visit,0,sizeof(visit));
    113     memset(cnt,0,sizeof(cnt));
    114     memset(graph,0,sizeof(graph));
    115     memset(grapht,0,sizeof(grapht));
    116     memset(graphnew,0,sizeof(graphnew));
    117     memset(use,0,sizeof(use));
    118     scanf("%d%d",&n,&m);
    119     n=(1<<n);
    120     int i,j,x,l,y,k;
    121     for(i=1;i<=m;i++)
    122     {
    123         x=y=0;
    124         scanf("%s",c);
    125         l=strlen(c);
    126         for(j=0;c[j]!='-';j++)
    127             x=x|(1<<(c[j]-'A'));
    128         j=j+2;
    129         for(j;j<l;j++)
    130             y=y|(1<<(c[j]-'A'));
    131         a[i].first=x; a[i].second=y;
    132     }
    133     for(i=1;i<n;i++)
    134         for(k=1;k<=m;k++)
    135             if((i&a[k].first)==a[k].first)
    136                 for(j=1;j<n;j++)
    137                     if(((i|a[k].second)&j)==j)
    138                         visit[i][j]=1;
    139     for(i=1;i<n;i++)
    140         for(j=1;j<n;j++)
    141             if(visit[i][j])
    142             {
    143                 add(i,j,graph);
    144                 add(j,i,grapht);
    145             }
    146 
    147     connect();
    148     reduce();
    149     solve();
    150     return 0;
    151 }

     

  • 相关阅读:
    android测试 adb命令、Monkey命令
    appium工作原理及启动方式
    python中自动化测试框架unittest
    python读取execl数据文件
    LeetCode#110 Balanced Binary Tree
    LeetCode#111 Minimum Depth of Binary Tree
    LeetCode#112 Path Sum
    数据链路层对应的子层
    数据链路层设备
    介质访问控制
  • 原文地址:https://www.cnblogs.com/myoi/p/2494885.html
Copyright © 2011-2022 走看看