A - Girls and Boys(匈牙利算法)

匈牙利算法

增广路求最大匹配的方法

https://blog.csdn.net/sunny_hun/article/details/80627351(形象生动)

最大独立集问题

如果U定义了G的一个完全子图,则它也定义了的一个空子图,反之亦然。所以在G的完备子图与的独立集之间有对应关系。特别的,G的一个最大完备子图定义了的一个最大独立集。
最大完备子图问题是指寻找图G的一个最大完备子图。类似地,最大独立集问题是指寻找图G的一个最大独立集。这两个问题都是NP-复杂问题。当用算法解决其中一个问题时,也就解决了另一个问题。例如,如果有一个求解最大完备子图问题的算法,则也能解决最大独立集问题,方法是首先计算所给图的补图,然后寻找补图的最大完备子图。
 

算法思想

定义一个图,图中每个顶点表示一个网组。当且仅当两个顶点对应的网组交叉时,它们之间有一条边。所以该图的一个最大独立集对应于非交叉网组的一个最大尺寸的子集。当网组有一个端点在路径顶端,而另一个在底端时,非交叉网组的最大尺寸的子集能在多项式时间(实际上是O(n2))内用动态规划算法得到。当一个网组的端点可能在平面中的任意地方时,不可能有在多项式时间内找到非交叉网组的最大尺寸子集的算法。
首先选择一点为树根,再按照深度优先遍历得到遍历序列,按照所得序列的反向序列的顺序进行贪心,对于一个即不属于支配集也不与支配集中的点相连的点来说,如果他的父节点不属于最大独立集,将其父节点加入到独立集。

A - Girls and Boys

二分图匹配+最大独立集+匈牙利算法

 

 
the second year of the university somebody started a study on the romantic relations between the students. The relation “romantically involved” is defined between one girl and one boy. For the study reasons it is necessary to find out the maximum set satisfying the condition: there are no two students in the set who have been “romantically involved”. The result of the program is the number of students in such a set.

The input contains several data sets in text format. Each data set represents one set of subjects of the study, with the following description:

the number of students
the description of each student, in the following format
student_identifier:(number_of_romantic_relations) student_identifier1 student_identifier2 student_identifier3 ...
or
student_identifier:(0)

The student_identifier is an integer number between 0 and n-1, for n subjects.
For each given data set, the program should write to standard output a line containing the result.
Input
7
0: (3) 4 5 6
1: (2) 4 6
2: (0)
3: (0)
4: (2) 0 1
5: (1) 0
6: (2) 0 1
3
0: (2) 1 2
1: (1) 0
2: (1) 0
Output
5
2
Sample Input
7
0: (3) 4 5 6
1: (2) 4 6
2: (0)
3: (0)
4: (2) 0 1
5: (1) 0
6: (2) 0 1
3
0: (2) 1 2
1: (1) 0
2: (1) 0
Sample Output
5
2
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1e3;
int a[maxn],b[maxn][150];
int f[maxn],vis[maxn];
int find(int p)
{
    int v;
    for(int i=0;i<a[p];i++)
    {
        v=b[p][i];
        if(!vis[v])
        {
            vis[v]=1;
            if(f[v]==-1||find(f[v]))
            {
                f[v]=p;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int t,n,x;
    while(cin>>t)
    {
        for(int i=0;i<t;i++)
        {
            scanf("%d: (%d)",&n,&a[i]);
            for(int j=0;j<a[n];j++)
            {
                scanf("%d",&b[n][j]);
            }
        }
        int ans=0;
        memset(f,-1,sizeof(f)); 
        for(int i=0;i<t;i++)
        {
            memset(vis,0,sizeof(vis));
            if(find(i))
              ans++;
        }
        ans/=2;
        cout<<t-ans<<endl;
    }
    return 0;
 } 

 

posted @ 2019-10-29 20:19  蓉~  阅读(128)  评论(0编辑  收藏  举报