二分图

来源:互联网 发布:收购博客玩家数据 编辑:程序博客网 时间:2024/06/03 21:18

拾金币

题目描述

ACM组织者请参赛队去发现王国玩游戏。共有n个队,组织者在途中放了m个金币,每个队需要最少找到一个金币,并带到终点换个相应的奖励。题目给出了每个队的起始位置,队伍的速度,金币的位置,终点的位置及到达终点所要求的时间。组织者想知道,最多能有多少个队获得奖励。
为了简化题目,路上没有障碍,参赛队可以直接走直线使时间最短,而且在拾金币时花费的时间可以忽略不记。

输入
先输入三个整数,gx,gy,t,分别表示终点位置坐标(0 < t < 1000)及所要求的时间,然后输入两个整数n,m,表示参赛队数及金币数,0 < m, n < 1000.
然后是n行数据,每行三个数,表示每一队的坐标及速度,也为整数。
然后是m行数据,每行两个数,表示每个金币的坐标。

输出
对每组数据,输出能够换得奖励的最大队伍的个数。
样例输入
8 1 2
2 2
2 1 3
4 1 3
5 1
7 1
样例输出
2

#include <bits/stdc++.h>using namespace std;typedef struct Data {    int x;    int y;    int speed;    double length;};typedef struct Coin {    int cx;    int cy;};int gx, gy, t;      // 终点坐标, 时间int n, m;           // n, 队伍数; m, 金币数int used[109], match[109];Data acm[100];Coin coin[100];int judge(int u,int i) {    // 判断u队是否能在规定时间内拿到i金币并到终点    double len = sqrt(pow(acm[u].x-coin[i].cx,2)+pow(acm[u].y-coin[i].cy,2))                + sqrt(pow(coin[i].cx-gx,2)+pow(coin[i].cy-gy,2));    return (len > acm[u].length) ? 0 : 1;}int dfs(int u) {    for (int i = 1; i <= m; i++) {        int x = judge(u, i);        if (x == 1 && !used[i]) {            used[i] = 1;            int t = match[i];            match[i] = u;            if (t == -1 || dfs(t)) {    // !!!                return 1;            }            match[i] = t;   // 若没有找到匹配的, 就还原数组        }    }    return 0;}int bipartite() {       // 匈牙利算法    int res = 0;    memset(match, -1, sizeof(match));    for (int u = 1; u <= n; u++) {        memset(used, 0, sizeof(used));        if (dfs(u)) {            res++;        }    }    return res;}int main() {    while (cin >> gx >> gy >> t) {        cin >> n >> m;        for (int i = 1; i <= n; i++) {            cin >> acm[i].x >> acm[i].y >> acm[i].speed;            acm[i].length = acm[i].speed * t;        }        for (int i = 1; i <= m; i++) {            cin >> coin[i].cx >> coin[i].cy;        }        int num = bipartite();        cout << num << endl;    }    return 0;}

过山车游戏

题目描述
RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?

输入
输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0 < K <= 1000, 1 <= N 和M <= 500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。

输出
对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数

样例输入
3 3 3
1 1
2 1
3 1
0

样例输出
1

#include <iostream>#include <cstring>using namespace std;int a[109][109], match[109], used[109];int girl, boy;int dfs(int u) {    for (int i = 1; i <= boy; i++) {        int x = a[u][i];        if (x == 1 && !used[i]) {            used[i] = 1;            int t = match[i];            match[i] = u;            if (t == -1 || dfs(t)) {    // !!!                return 1;            }            match[i] = t;        }    }    return 0;}int bipartite() {   // 匈牙利算法    int res = 0;    memset(match, -1, sizeof(match));    for (int u = 1; u <= girl; u++) {        memset(used, 0, sizeof(used));        if (dfs(u)) {            res++;        }    }    return res;}int main() {    int n, g, b, r;    while (cin >> n) {        if (!n) break;        cin >> girl >> boy;        memset(a, 0, sizeof(a));        for (int i = 1; i <= n; i++) {            cin >> g >> b;            a[g][b] = 1;        }        r = bipartite();        cout << r << endl;    }    return 0;}

Air Raid

题目描述
Consider a town where all the streets are one-way and each street leads from one intersection to another. It is also known that starting from an intersection and walking through town’s streets you can never reach the same intersection i.e. the town’s streets form no cycles.

With these assumptions your task is to write a program that finds the minimum number of paratroopers that can descend on the town and visit all the intersections of this town in such a way that more than one paratrooper visits no intersection. Each paratrooper lands at an intersection and can visit other intersections following the town streets. There are no restrictions about the starting intersection for each paratrooper.

输入
Your program should read sets of data. The first line of the input file contains the number of the data sets. Each data set specifies the structure of a town and has the format:

no_of_intersections
no_of_streets
S1 E1
S2 E2
……
Sno_of_streets Eno_of_streets

The first line of each data set contains a positive integer no_of_intersections (greater than 0 and less or equal to 120), which is the number of intersections in the town. The second line contains a positive integer no_of_streets, which is the number of streets in the town. The next no_of_streets lines, one for each street in the town, are randomly ordered and represent the town’s streets. The line corresponding to street k (k <= no_of_streets) consists of two positive integers, separated by one blank: Sk (1 <= Sk <= no_of_intersections) - the number of the intersection that is the start of the street, and Ek (1 <= Ek <= no_of_intersections) - the number of the intersection that is the end of the street. Intersections are represented by integers from 1 to no_of_intersections.

There are no blank lines between consecutive sets of data. Input data are correct.

输出
The result of the program is on standard output. For each input data set the program prints on a single line, starting from the beginning of the line, one integer: the minimum number of paratroopers required to visit all the intersections in the town.

样例输入
2
4
3
3 4
1 3
2 3
3
3
1 3
1 2
2 3

样例输出
2
1

提示
二分匹配 DAG图

/** * Air Raid * 伞兵空袭, 城市有intersections和streets, intersection是单向的, 从A intersection指向B intersection. * 伞兵走过即算占领, 问最少要多少伞兵可占领所有intersections ? */#include <iostream>#include <cstring>using namespace std;int Map[109][109];int used[109], match[109];int intersections, streets;int dfs(int u) {    for(int i = 1; i <= streets; i++) {        int x = Map[u][i];        if(x == 1 && !used[i]) {            used[i] = 1;            int t = match[i];            if(t == -1 || dfs(t)) { // !!!                return 1;            }            match[i] = t;        }    }    return 0;}int bipartite() {       // 匈牙利算法    int res = 0;    memset(match, -1, sizeof(match));    for(int u = 1; u <= intersections; u++) {        memset(used, 0, sizeof(used));        if(dfs(u)) {            res++;        }    }    return res;}int main() {    int T, from, to;    cin >> T;    while (T--) {        cin >> intersections >> streets;        memset(Map, 0, sizeof(Map));        for (int i = 1; i <= streets; i++) {            cin >> from >> to;            Map[from][to] = 1;        }        cout << intersections - bipartite() << endl;    }    return 0;}
0 0
原创粉丝点击