POJ 1698 (二分图的多重匹配)

转载:http://www.cppblog.com/MatoNo1/archive/2011/03/26/142766.aspx

  我们知道在一个图中,每个点最多只能匹配一条边的情况,是二分图的最大匹配问题.然而还有种情况是:每个点可以匹配多条边,但有上限,假设为L.即Li表示最多点i可以和Li条边相关联.

二分图多重最大匹配:

1.建立一个源点S和汇点T.

2.S指向x顶点,容量为x内点的L值.y顶点指向T,容量为y内点的L值.

3.原图中的各边在新图中仍存在,容量为1.

那么S到T的最大流就是多重最大匹配.

例如POJ1698:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #define _clr(x, y) memset(x, y, sizeof(x))
 5 #define Min(x, y) (x < y ? x : y)
 6 #define Max(x, y) (x > y ? x : y)
 7 #define INF 0x3f3f3f3f
 8 #define N 400
 9 using namespace std;
10
11 int edge[N][N], dist[N];
12 int T, S, Sum, n;
13 bool used[N];
14
15 bool bfs()
16 {
17     _clr(dist, -1);
18     queue<int> Q;
19     dist[S] = 0;
20     Q.push(S);
21     while(!Q.empty())
22     {
23         int u = Q.front();
24         Q.pop();
25         for(int v=0; v<=T; v++)
26         {
27             if(edge[u][v] && dist[v]<0)
28             {
29                 dist[v] = dist[u] + 1;
30                 Q.push(v);
31             }
32         }
33     }
34     return dist[T]>0? 1 : 0;
35 }
36
37 int dfs(int u, int alpha)
38 {
39     int a;
40     if(u==T) return alpha;
41     for(int i=0; i<=T; i++)
42     {
43         if(edge[u][i] && dist[i]==dist[u]+1 && (a=dfs(i, Min(alpha, edge[u][i]))))
44         {
45             edge[u][i] -= a;
46             edge[i][u] += a;
47             return a;
48         }
49     }
50     dist[u] = -1;
51     return 0;
52 }
53 void Dinic()
54 {
55     int ans=0, a=0;
56     while(bfs())
57         while(a=dfs(0, INF)) ans += a;
58     printf ("%s\n", ans==Sum ? "Yes" : "No");
59 }
60
61 int main()
62 {
63     int K, week[10];
64     scanf("%d", &K);
65     while(K--)
66     {
67         int day = 0, d, w;
68         scanf("%d", &n);
69         Sum = 0, S=0;
70         _clr(week, 0);
71         _clr(edge, 0);
72         for(int i=1; i<=n; i++)    // 1--n之间表示电影,n+1---T之间表示天数!
73         {
74             for(int i1=0; i1<7; i1++) scanf("%d", week+i1);
75             scanf("%d%d", &d, &w);
76             day = Max(day, w);
77             edge[S][i] = d;     // 源点向每个电影节点 x 连接一条权值为拍摄此电影所需天数的值.
78             Sum += d;
79
80             for(int j=0; j<w; j++) // W周之内完成.
81             {
82                 for(int k=0; k<7; k++)
83                     if(week[k])
84                         edge[i][n+j*7+k+1] = 1;    //第i部电影可以在w周内的周k拍摄.
85             }
86             T = day*7+n+1;
87             for(int i=n+1; i<T; i++)
88                 edge[i][T] = 1;
89         }
90         Dinic();
91     }
92     return 0;
93 }
时间: 2024-10-15 15:16:31

POJ 1698 (二分图的多重匹配)的相关文章

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加

POJ 2195 二分图最小权匹配KM算法

本来是打算昨天晚上写的, 昨天网速渣的连CSDN都进不去,没办法 只能现在来写了 先写写对KM算法的理解,KM算法是对每个点设置一个顶标,只有当边长等于两边点的顶标之和的时候才进行增广,这样就能保证得到的一定是最大权匹配. 如果找不到匹配的时候就对交替路中X集合的顶标减少一个d Y集合的顶标增加一个d. 这样两个点都在交替路中的时候x[i]+y[i]的和不边 X在 Y不在的时候x[i]+y[i]减少,可能就会为图增加一对匹配. X不在Y在的时候x[i]+y[i]增加, 原来不在现在依然不在其中.

HDU1669 Jamie&#39;s Contact Groups (二分+二分图的多重匹配)

多重匹配:一对多的二分图的多重匹配.二分图的多重匹配算法的实现类似于匈牙利算法,对于集合X中的元素xi,找到一个与其相连的元素yi后,检查匈牙利算法的两个条件是否成立,若yi未被匹配,则将 xi,yi匹配.否则,如果与yi匹配的元素已经达到上限,那么在所有与yi匹配的元素中选择一个元素,检查是否能找到一条增广路径,如果能,则让出位置,让xi与yi匹配. match[i][j]表示X集合中的Xi点与y集合中的j个点相连接(一对多) #include<cstdio> #include<ios

【二分图】二分图的多重匹配

某些问题中,会遇到一对多的二分图模型,即允许集合Y中的一个元素和集合X中的多个元素匹配(通常有一个最大限制n) /*二分图多重匹配算法*/ const int MAXN=1001;//最大顶点数 int bmap[MAXN][MAXN];//二分图 bool bmask[MAXN];//寻找增广路径是的标志数组 int nx,ny;//左右集合的顶点数目 int vcy[MAXN];//vcy[i],右集合i顶点匹配到左集合的顶点数目 int cy[MAXN][MAXN];//cy[i][j]右

hdu 3605 Escape 二分图的多重匹配(匈牙利算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 8001    Accepted Submission(s): 1758 Problem Description 2012 If this is the end of th

poj 1698 Alice&#39;s Chance 二分图多重匹配

题意: 一个演员要拍n部电影,每部电影只能在一周的特定几天拍(如周2,周4,周5),第i部电影要拍di天,必须要在wi周拍完,问演员是否可以完成任务. 分析: 建二分图,转化为二分图的多重匹配. 代码: //poj 1698 //sep9 #include <iostream> using namespace std; const int maxX=64*7; const int maxY=64; int g[maxX][maxY],match[maxY][maxX]; int vis[max

POJ - 2289 Jamie&#39;s Contact Groups (二分图多重匹配)

题意:N个人,M个团体.每个人有属于自己的一些团体编号.将每个人分配到自己属于的团体中,问这个人数最多的团体其人数最小值是多少. 分析:一个一对多的二分图匹配,且是最大值最小化问题.二分图的多重匹配建立在匈牙利算法的基础上,令每个Y部的点可匹配多个点,但是规定其上限,超过上限就要在已有的匹配点中寻找增广路.对于X部的点,只要有一个点没有被匹配,那么算法失败.以此二分确定答案,注意二分的姿势... 该题可做模板. #include<iostream> #include<stdio.h>

Jamie&#39;s Contact Groups(二分图多重匹配+二分)(网络流)

Jamie's Contact Groups Time Limit:7000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2289 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list

POJ2289:Jamie&#39;s Contact Groups(二分+二分图多重匹配)

Jamie's Contact Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) 题目链接:http://poj.org/problem?id=2289 Description: Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long