zoukankan      html  css  js  c++  java
  • poj1904

    题目来源:http://poj.org/problem?id=1904

    大意:N个王子和N个美女配对,每个王子喜欢一个或多个美女,大臣已经配好了一个列表,但是国王想知道每个王子和美女的可行匹配。就是求出每个王子可以选择哪些美女

    思路:对于每对男女u,v,连边(u,u+n),而输入的最后给出一个可行匹配,则对于每个美女v和配对的王子u,连边(v+n,u),然后求出图的强联通分量,最后计数输出就是了。

    这是用vector储存的程序,5000ms+

    View Code
     1 #include <stdio.h>
     2 #include <string>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 #define NN 5005
     8 vector <int> a[NN];
     9 vector <int> b[NN];
    10 int real[NN],low[NN],p[NN],color[NN];
    11 bool f[NN];
    12 int n,top,total,timee;
    13 
    14 void tarjan(int h)
    15 {
    16      p[++top]=h;
    17      f[h]=true;
    18      real[h]=low[h]=++timee;
    19      for (int i=0;i<a[h].size();i++)
    20      {
    21          if (!real[a[h][i]])
    22          {
    23                          tarjan(a[h][i]);
    24                          low[h]=min(low[h],low[a[h][i]]);
    25          }
    26          else if (f[a[h][i]]) low[h]=min(low[h],real[a[h][i]]);
    27      }
    28      
    29      if (real[h]==low[h])
    30      {
    31                          total++;
    32                          while (p[top+1]!=h)
    33                          {
    34                                color[p[top]]=total;
    35                                f[p[top]]=false;
    36                                top--;
    37                          }
    38      }
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%d",&n);
    44     int m,x;
    45     for (int i=1;i<=n;i++)
    46     {
    47         scanf("%d",&m);
    48         for (int j=0;j<m;j++)
    49         {
    50             scanf("%d",&x);
    51             a[i].push_back(x+n);
    52         }
    53     }
    54     for (int i=1;i<=n;i++)
    55     {
    56         scanf("%d",&x);
    57         a[x+n].push_back(i);
    58     }
    59     
    60     memset(real,0,sizeof(real));
    61     memset(low,0,sizeof(low));
    62     memset(p,0,sizeof(p));
    63     memset(f,false,sizeof(f));
    64     top=total=timee=0;
    65     for (int i=1;i<=n;i++)
    66         if (!real[i]) 
    67            tarjan(i);
    68     
    69     for (int i=1;i<=n;i++)
    70         b[i].clear();
    71     for (int i=1;i<=n;i++)
    72     {
    73         for (int j=0;j<a[i].size();j++)
    74             if (color[i]==color[a[i][j]])
    75             b[i].push_back(a[i][j]-n);
    76         sort(b[i].begin(),b[i].end());
    77     }
    78     for (int i=1;i<=n;i++)
    79     {
    80         printf("%d",b[i].size());
    81         for (int j=0;j<b[i].size();j++)
    82             printf(" %d",b[i][j]);
    83         printf("\n");
    84     }
    85     return 0;
    86 }

    这是用池子法(前向星法)写的程序,3000ms+

    View Code
      1 #include <stdio.h>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 
      6 #define maxn 20005
      7 #define maxm 2000005
      8 struct node {
      9        int y,next;
     10 }p[maxm];
     11 
     12 int head[maxn],a[maxm];
     13 int n,m,cl;
     14 bool instack[maxn];
     15 int real[maxn],low[maxn],stack[maxn],color[maxn];
     16 int depth,top,total;
     17 
     18 void add(int x,int y)
     19 {
     20      p[++cl].y=y;
     21      p[cl].next=head[x];
     22      head[x]=cl;
     23 }
     24 
     25 void dfs(int x)
     26 {
     27      int y;
     28      real[x]=low[x]=++depth;
     29      instack[x]=true;
     30      stack[++top]=x;
     31      for (int i=head[x];i!=-1;i=p[i].next)
     32      {
     33          y=p[i].y;
     34          if (!real[y])
     35          {
     36                       dfs(y);
     37                       low[x]=min(low[x],low[y]);
     38          }
     39          else if (instack[y])
     40               low[x]=min(low[x],real[y]);
     41      }
     42      
     43      if (real[x]==low[x])
     44      {
     45                          total++;
     46                          while (stack[top+1]!=x)
     47                          {
     48                                y=stack[top--];
     49                                instack[y]=false;
     50                                color[y]=total;
     51                          }
     52      }
     53 }
     54      
     55 
     56 void tarjan()
     57 {
     58      memset(real,0,sizeof(real));
     59      memset(low,0,sizeof(low));
     60      memset(instack,false,sizeof(instack));
     61      depth=top=total=0;
     62      for (int i=1;i<=n*2;i++)
     63          if (!real[i])
     64             dfs(i);
     65 }
     66 
     67 void solve()
     68 {
     69      int y;
     70      for (int i=1;i<=n;i++)
     71      {
     72          top=0;
     73          for (int j=head[i];j!=-1;j=p[j].next)
     74          {
     75              y=p[j].y;
     76              if (color[y]==color[i])
     77                 a[top++]=y-n;
     78          }
     79          printf("%d",top);
     80          sort(a,a+top);
     81          for (int j=0;j<top;j++)
     82              printf(" %d",a[j]);
     83          printf("\n");
     84      }
     85 }
     86 
     87 int main()
     88 {
     89     scanf("%d",&n);
     90     int x,y;
     91     memset(head,-1,sizeof(head));
     92     cl=0;
     93     for (int i=1;i<=n;i++)
     94     {
     95         scanf("%d",&y);
     96         while (y--)
     97         {
     98               scanf("%d",&x);
     99               add(i,x+n);
    100         }
    101     }
    102     for (int i=1;i<=n;i++)
    103     {
    104         scanf("%d",&x);
    105         add(x+n,i);
    106     }
    107     tarjan();
    108     solve();
    109     return 0;
    110 }
  • 相关阅读:
    centos7安装sshd
    Linux搭建redist-cluster集群
    nginx离线安装,反向代理,负载均衡
    2017/12/31Java基础学习——数组输出の通过Arrays.toString()方法
    Java代码编写规范
    2017/12/27java基础学习——遇到的不懂问题
    2017/12/23Java基础学习——如何通过记事本编写代码,并通过dos界面运行Java源文件
    ZOJ3880 Demacia of the Ancients【序列处理+水题】
    ZOJ3869 Ace of Aces【序列处理】
    ZOJ3872 Beauty of Array【DP】
  • 原文地址:https://www.cnblogs.com/ay27/p/2651409.html
Copyright © 2011-2022 走看看