zoukankan      html  css  js  c++  java
  • POJ1904(King's Quest)

    题目链接

    此题初看起来是一个二分匹配的问题,一个国王有n个儿子,将要与n个女孩结婚,已知每个儿子喜欢某几个女孩,并给出了一个初始匹配,问题是求每个儿子可能与哪些他喜欢的女孩结婚,一旦他选一个结婚后,其他的儿子仍能选到自己喜欢的人结婚。若直接枚举个中可能,然后用匈牙利算法求完美匹配判断,这样的话时间复杂度是O(n5),毫无疑问会超时。在这里,题目给出里一个初始完美匹配,必须加以利用。我们可以把初始完美匹配中的每一对看成结点进行构图,因此每个结点包含一个男孩和一个女孩,若结点i中的男孩喜欢结点j中的女孩,就在结点i与结点j之间连一条有向边,这样问题就转化为求强分图,每个男孩可以与他喜欢的并且与他在同一个强分图中的一个女孩结婚且不影响到其他人。求强分图,我用的是两次dfs的算法。

    View Code
     1 #include <stdio.h>
    2 #include <string.h>
    3 #define CLR(a) (memset(a,0,sizeof(a)))
    4 #define N 2005
    5 char vis[N],g[N][N];
    6 int boy[N],girl[N],n;
    7 int ord[N],id[N],cnt;
    8 void dfs(int u)
    9 {
    10 int i,v;
    11 vis[u]=1;
    12 for(i=0;i<n;i++)
    13 {
    14 if(g[u][i])
    15 {
    16 v=boy[i];
    17 if(!vis[v]) dfs(v);
    18 }
    19 }
    20 ord[cnt++]=u;
    21 }
    22 void rdfs(int u)
    23 {
    24 int i=girl[u],v;
    25 vis[u]=1,id[u]=cnt;
    26 for(v=0;v<n;v++)
    27 {
    28 if(g[v][i]&&!vis[v]) rdfs(v);
    29 }
    30 }
    31 void kosaraju()
    32 {
    33 int i,j,v,t,ans[N],num;
    34 CLR(vis);
    35 for(i=0,cnt=0;i<n;i++)
    36 {
    37 if(!vis[i]) dfs(i);
    38 }
    39 CLR(vis);
    40 for(t=n-1,cnt=0;t>=0;t--)
    41 {
    42 i=ord[t];
    43 if(!vis[i])
    44 {
    45 rdfs(i);
    46 cnt++;
    47 }
    48 }
    49 for(i=0;i<n;i++)
    50 {
    51 for(v=0,num=0;v<n;v++)
    52 {
    53 if(!g[i][v]) continue;
    54 j=boy[v];
    55 if(id[i]==id[j]) ans[num++]=v+1;
    56 }
    57 printf("%d",num);
    58 for(j=0;j<num;j++) printf(" %d",ans[j]);
    59 printf("\n");
    60 }
    61 }
    62 int main()
    63 {
    64 int i,j,k;
    65 while(scanf("%d",&n)!=EOF)
    66 {
    67 CLR(g);
    68 for(i=0;i<n;i++)
    69 {
    70 scanf("%d",&k);
    71 while(k--)
    72 {
    73 scanf("%d",&j);
    74 g[i][j-1]=1;
    75 }
    76 }
    77 for(i=0;i<n;i++)
    78 {
    79 scanf("%d",&j);
    80 girl[i]=j-1;
    81 boy[girl[i]]=i;
    82 }
    83 kosaraju();
    84 }
    85 return 0;
    86 }
  • 相关阅读:
    学习进度表
    mysql实现跨库查询
    jmeter分布式(1台Windows,一台Mac,亲测可用互相使用)
    解决appium 连接真机Android 9启动报错.....shell "ps 'uiautomator'
    使用fiddler抓包修改请求/返回的数据
    adb 获取当前界面activity
    使用adb 命令获取APP包名
    jmeter实现登录并设置token为全局变量
    python3 SystemError: Parent module '' not loaded, cannot perform relative import
    adb 运行提示error: cannot connect to daemon
  • 原文地址:https://www.cnblogs.com/algorithms/p/2432475.html
Copyright © 2011-2022 走看看