UVA10505 Montesco vs Capuleto【DFS】

Romeo and Juliet have finally decided to get married. But preparing the wedding party will not be so easy, as it is well-known that their respective families –the Montesco and the Capuleto– are bloody enemies. In this problem you will have to decide which person to invite and which person not to invite, in order to prevent a slaugther.
    We have a list of N people who can be invited to the party or not. For every person i, we have a list of his enemies: E1, E2, . . . , Ep. The “enemy” relationship has the following properties:
Anti-transitive. If a is an enemy of b, and b is an enemy of c, then a is a friend of c. Also, the enemies of the friends of a are his enemies, and the friends of the friends of a are his friends.
Symmetrical. If a is an enemy of b, then b is an enemy of a (although it may not be indicated in his list of enemies).
    One person will accept an invitation to the party if, and only if, he is invited, all his friends are invited and none of his enemies is invited. You have to find the maximum number of people that can be invited, so that all of them accept their invitation.
    For instance, if N = 5, and we know that: 1 is enemy of 3, 2 is enemy of 1, and 4 is enemy of 5, then we could invite a maximum of 3 people. These people could be 2, 3 and 4, but for this problem we only want the number of people invited.
Input
The first line of the input file contains the number M of test cases in this file. A blank line follows this number, and a blank line is also used to separate test cases. The first line of each test case contains an integer N, indicating the number of people who have to be considered. You can assume that N ≤ 200. For each of these N people, there is a line with his list of enemies. The first line contains the list of enemies of person 1, the second line contains the list of enemies of person 2, and so on. Each list of enemies starts with an integer p (the number of known enemies of that person) and then, there are p integers (the p enemies of that person). So, for example, if a person’s enemies are 5 and 7, his list of enemies would be: ‘2 5 7’.
Output
For each test case, the output should consist of a single line containing an integer, the maximum number of people who can be invited, so that all of them accept their invitation.
Sample Input
3
5
1 3
1 1
0
1 5
0
8
2 4 5
2 1 3
0
0
0
1 3
0
1 5
3
2 2 3
1 3
1 1
Sample Output
3
5
0

问题链接UVA10505 Montesco vs Capuleto
问题简述:(略)
问题分析
    有N个人要参加宴会,人与人之间有敌对关系,这种关系是对称的,并且可传递(敌人的敌人是朋友)。求最多可以邀请多少人。
    人与人关系可以分成分成四种,1.没有关系,2.敌对关系,3.朋友关系(敌人的敌人是朋友),4.矛盾关系(又是朋友又是敌人)。
    这个问题按着色问题来处理,可以用DSF来解。实际上,用并查集来解应该会更为简单一些。这个问题也可以用二分图的方法来解。这是一个经典的问题,各种解法值得都试一下。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* UVA10505 Montesco vs Capuleto */

#include <bits/stdc++.h>

using namespace std;

const int N = 200;
int n, g[N + 1][N + 1], vis[N + 1];

void dfs(int u, int& a, int& b, int& ok, int color)
{
    if (vis[u])
        ok &= (vis[u] == color);
    else {
        vis[u] = color;
        a++;
        for (int v = 1; v <= n; v++)
            if (g[u][v]) dfs(v, b, a, ok, 3 - color);
    }
}

int main()
{
    int m;
    scanf("%d", &m);
    while(m--) {
        memset(g, 0, sizeof(g));

        // 读入数据
        scanf("%d", &n);
        for(int u = 1; u <= n; u++) {
            int k, v;
            scanf("%d", &k);
            for(int i = 1; i <= k; i++) {
                scanf("%d", &v);
                g[u][v] = g[v][u] = 1;
            }
        }

        memset(vis, 0, sizeof(vis));
        int sum = 0;
        for(int u = 1; u <= n; u++) {
            if(vis[u] == 0) {
                int a = 0, b= 0, ok = 1;
                dfs(u, a, b, ok, 1);
                sum += ok * max(a, b);
            }
        }

        printf("%d\n", sum);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/89815968
VS