• King's Quest POJ


    题目链接:https://cn.vjudge.net/problem/POJ-1904

    自己一开始的想法,打算用匈牙利算法实现,找二分图的最大匹配。但是打了打发现,不太好实现。原因如下:匈牙利算法是不停的找增广路。如果这个题用匈牙利算法实现的时候,就是这个地方:

     1 bool Find(int t)
     2 {
     3     for(int i=1; i<=m; i++)
     4     {
     5         if(line[t][i]&&Exit[i]==0)
     6         {
     7             Exit[i]=1;
     8             if(net[i]==0||Find(net[i]))
     9             {
    10                 net[i]=t;
    11                 return true;
    12             }
    13         }
    14     }
    15 }

    ,这个是找到合法的就返回,无法把所有的情况都找到,所以这个方法不行。

    然后再去想tarjan算法,找缩点,也就是图上的两点都能都到达,如果是王子向喜欢的公主连线的话,连一条单向边,如果是公主喜欢的王子的话,然后再从公主连向王子一条单向边,这样,就能够在最大匹配的图上实现一个连通图的建立.

    但是注意这个题有个坑点,在构成连通图的时候,有的王子不喜欢某个公主,但是在图上也有可能通过别的点联通起来,这个时候就需要特判一下了。

    AC代码:

      1 #include<iostream>
      2 #include<stack>
      3 #include<iomanip>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<string>
      7 #include<cstring>
      8 #include<queue>
      9 #include<vector>
     10 #include<stdio.h>
     11 #include<map>
     12 using namespace std;
     13 # define inf 0x3f3f3f3f
     14 # define ll long long
     15 const int N = 4000+100 ;
     16 const int M = 250000+100 ;
     17 struct node
     18 {
     19     int to;
     20     int nex;
     21 } edge[M];
     22 int head[M],low[N],dfn[N],istack[N];
     23 int num,ind,col,n,m;
     24 stack<int>q;
     25 vector<int>wakaka[N];
     26 vector<int>w1;
     27 vector<int>ans[N];
     28 int Map[2010][2010];
     29 void init()
     30 {
     31     while(!q.empty())q.pop();
     32     memset(head,-1,sizeof(head));
     33     num=0,ind=0,col=0;
     34     memset(low,0,sizeof(low));
     35     memset(dfn,0,sizeof(dfn));
     36     memset(istack,0,sizeof(istack));
     37 }
     38 void addedge(int fr,int to)
     39 {
     40     edge[num].to=to;
     41     edge[num].nex=head[fr];
     42     head[fr]=num++;
     43 }
     44 void tarjan(int u,int root)
     45 {
     46     q.push(u);
     47     low[u]=dfn[u]=++ind;
     48     for(int i=head[u]; i!=-1; i=edge[i].nex)
     49     {
     50         int v=edge[i].to;
     51         if(dfn[v]==0)
     52         {
     53             tarjan(v,u);
     54             low[u]=min(low[u],low[v]);
     55         }
     56         else if(istack[v]==0)
     57         {
     58             low[u]=min(low[u],dfn[v]);
     59         }
     60     }
     61     if(low[u]==dfn[u])
     62     {
     63         int t;
     64         col++;
     65         do
     66         {
     67             t=q.top();
     68             q.pop();
     69             istack[t]=col;
     70             wakaka[col].push_back(t);
     71         }
     72         while(t!=u);
     73     }
     74 }
     75 int main()
     76 {
     77     init();
     78     scanf("%d",&n);
     79     int t;
     80     for(int i=1; i<=n; i++)
     81     {
     82         scanf("%d",&m);
     83         for(int j=1; j<=m; j++)
     84         {
     85             scanf("%d",&t);
     86             addedge(i,t+n);
     87             Map[i][t]=1;
     88         }
     89     }
     90     for(int i=1; i<=n; i++)
     91     {
     92         scanf("%d",&t);
     93         addedge(t+n,i);
     94        // Map[t][i]=1;
     95     }
     96     for(int i=1; i<=n; i++)
     97     {
     98         if(dfn[i]==0)
     99         {
    100             tarjan(i,1);
    101         }
    102     }
    103     for(int i=1; i<=col; i++)
    104     {
    105         sort(wakaka[i].begin(),wakaka[i].end());
    106         int len=wakaka[i].size();
    107         for(int j=0; j<len; j++)
    108         {
    109             int u=wakaka[i][j];
    110             if(u<=n)w1.push_back(u);
    111             else 
    112             {
    113                 int len2=w1.size();
    114                 for(int k=0; k<len2; k++)
    115                 {
    116                 if(Map[w1[k]][u-n])//判断是不是有相互喜欢的关系
    117                     ans[w1[k]].push_back(u-n);
    118                 }
    119             }
    120         }
    121         w1.clear();
    122     }
    123     for(int i=1; i<=n; i++)
    124     {
    125     sort(ans[i].begin(),ans[i].end());
    126         int len=ans[i].size();
    127         printf("%d",len);
    128         for(int j=0; j<len; j++)
    129         {
    130             printf(" %d",ans[i][j]);
    131         }
    132         printf("
    ");
    133     }
    134     return 0;
    135 }
  • 相关阅读:
    浅析Vue3相关基础知识:Vue3应用配置、重写的vmodel、emits 选项、getCurrentInstance()获取实例、采用mitt实现全局通讯、vuerouter的新特性
    Vue3结合TS项目开发实践:Composition API的风格理念、关注点分离、如何组织TS进行项目开发(采用声明文件来管理接口及所需类型/目录结构推荐)
    TypeScript类型守卫、联合类型、交叉类型
    Android开发历程_14(广播机制)
    OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)
    OpenGL_Qt学习笔记之_06(纹理滤波、光照和色彩融合)
    Qt学习之路_12(简易数据管理系统)
    特征点检测学习_2(surf算法)
    Kinect+OpenNI学习笔记之2(获取kinect的颜色图像和深度图像)
    PCA算法学习_1(OpenCV中PCA实现人脸降维)
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262802.html
Copyright © 2020-2023  润新知