POJ 1325-Machine Schedule(二分圖匹配-匈牙利演算法)
Machine Schedule
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 14308 | Accepted: 6107 |
Description
As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduling problems differ widely in the nature of the constraints that must be satisfied and the type of schedule desired. Here
we consider a 2-machine scheduling problem.
There are two machines A and B. Machine A has n kinds of working modes, which is called mode_0, mode_1, ..., mode_n-1, likewise machine B has m kinds of working modes, mode_0, mode_1, ... , mode_m-1. At the beginning they are both work at mode_0.
For k jobs given, each of them can be processed in either one of the two machines in particular mode. For example, job 0 can either be processed in machine A at mode_3 or in machine B at mode_4, job 1 can either be processed in machine A at mode_2 or in machine B at mode_4, and so on. Thus, for job i, the constraint can be represent as a triple (i, x, y), which means it can be processed either in machine A at mode_x, or in machine B at mode_y.
Obviously, to accomplish all the jobs, we need to change the machine's working mode from time to time, but unfortunately, the machine's working mode can only be changed by restarting it manually. By changing the sequence of the jobs and assigning each job to a suitable machine, please write a program to minimize the times of restarting machines.
There are two machines A and B. Machine A has n kinds of working modes, which is called mode_0, mode_1, ..., mode_n-1, likewise machine B has m kinds of working modes, mode_0, mode_1, ... , mode_m-1. At the beginning they are both work at mode_0.
For k jobs given, each of them can be processed in either one of the two machines in particular mode. For example, job 0 can either be processed in machine A at mode_3 or in machine B at mode_4, job 1 can either be processed in machine A at mode_2 or in machine B at mode_4, and so on. Thus, for job i, the constraint can be represent as a triple (i, x, y), which means it can be processed either in machine A at mode_x, or in machine B at mode_y.
Obviously, to accomplish all the jobs, we need to change the machine's working mode from time to time, but unfortunately, the machine's working mode can only be changed by restarting it manually. By changing the sequence of the jobs and assigning each job to a suitable machine, please write a program to minimize the times of restarting machines.
Input
The input file for this program consists of several configurations. The first line of one configuration contains three positive integers: n, m (n, m < 100) and k (k < 1000). The following k lines give the constrains of the k jobs, each line is a triple: i,
x, y.
The input will be terminated by a line containing a single zero.
The input will be terminated by a line containing a single zero.
Output
The output should be one integer per line, which means the minimal times of restarting machine.
Sample Input
5 5 10 0 1 1 1 1 2 2 1 3 3 1 4 4 2 1 5 2 2 6 2 3 7 2 4 8 3 3 9 4 3 0
Sample Output
3
Source
題目意思:
有兩臺機器A和B,A有N種工作模式0~N-1,B有M種工作模式0~M-1,剛開始時的初始狀態,A和B都在模式0。
給定K個作業,每個作業可以工作在特定的A和B的模式下。樣例中,0 1 1 表示作業0可以工作在A的1狀態和B的1狀態。
為了完成作業,機器必須不斷的切換模式,試著寫程式實現:改變機器的順序,給每個作業分配合適的作業,使得重啟機器次數最少。
解題思路:
構造二部圖,用匈牙利演算法做二分圖匹配。
![](https://i.iter01.com/images/559647ef2c082e8fb25d4fc2ce2069998d64515bcda2c41ad1da7defa26c05b2.png)
如果某作業任務可以在A的i狀態和B的j狀態上完成,則從Ai到Bj連一條邊,這樣構造二部圖。
對於樣例來說,選擇A狀態的1和2,B狀態的3。
DFS和BFS效率和記憶體幾乎完全一樣…
![](https://i.iter01.com/images/3c543110fbec1cbed6d159608eea260cc4a2792dc0fa91d17b7200f3546f30c1.png)
①DFS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define maxn 1010
#define INF 0xfffffff
using namespace std;
int nx,ny;//X與Y集合中元素的個數
int g[maxn][maxn];//邊的鄰接矩陣
int cx[maxn],cy[maxn];//cx[i]表示最終求得的最大匹配中與Xi匹配的頂點,cy[i]同理
int mk[maxn];//mark,記錄頂點訪問狀態
int path(int u)
{
//for(int v=0; v<ny; ++v)//A與B兩機器初始為0,所以0狀態不必重啟,從1開始
for(int v=1; v<ny; ++v)//考慮Yi的頂點v
if(g[u][v]&&!mk[v])//v與u鄰接,且沒有訪問過
{
mk[v]=1;//訪問v
if(cy[v]==-1||path(cy[v]))//如果v沒有匹配,或者v已經匹配但是從cy[v]出發可以找到一條增廣路
{
cx[u]=v;//v匹配給u
cy[v]=u;//u匹配給v
return 1;//找到可增廣路
}
}
return 0;//不存在從u出發的增廣路
}
int MaxMatch()//匈牙利演算法
{
int res=0;//所求得的最大匹配
memset(cx,-1,sizeof(cx));//從0開始匹配增廣,所以初始化為-1
memset(cy,-1,sizeof(cy));
// for(int i=0; i<=nx; ++i)
for(int i=1; i<=nx; ++i)//A與B兩機器初始為0,所以0狀態不必重啟,從1開始
if(cx[i]==-1)//從每個未蓋點出發進行尋找增廣路
{
memset(mk,0,sizeof(mk));
res+=path(i);//每找到一條增廣路,可使得匹配數加1
}
return res;
}
int main()
{
int k;
while(cin>>nx&&nx!=0)
{
cin>>ny>>k;
memset(g,0,sizeof(g));
int i,a,x,y;
for(i=0; i<k; ++i)
{
cin>>a>>x>>y;
g[x][y]=1;
}
cout<<MaxMatch()<<endl;
}
return 0;
}
/*
5 5 10
0 1 1
1 1 2
2 1 3
3 1 4
4 2 1
5 2 2
6 2 3
7 2 4
8 3 3
9 4 3
0
*/
②BFS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define maxn 1010
#define INF 0xfffffff
using namespace std;
int nx,ny;//X與Y集合中元素的個數
int g[maxn][maxn];//邊的鄰接矩陣
int cx[maxn],cy[maxn];//cx[i]表示最終求得的最大匹配中與Xi匹配的頂點,cy[i]同理
int pred[maxn];//用來記錄交錯軌,同時也記錄Y集合中的頂點是否遍歷過
int que[maxn];//陣列模擬佇列
int MaxMatch()
{
int i,j,y;
int cur,tail;//佇列首位位置的下標
int res=0;//求得的最大匹配數
memset(cx,-1,sizeof(cx));//初始化所有點為未被匹配的狀態
memset(cy,-1,sizeof(cy));
//for(i=0; i<nx; ++i)
for(i=1; i<nx; ++i)//對X集合中的每個未蓋點i進行一次BFS找交錯軌
{
if(cx[i]!=-1) continue;
//for(j=0; j<ny; ++j)
for(j=1; j<ny; ++j)
pred[j]=-2;//-2是初始值
cur=tail=0;//初始化佇列
//for(j=0; j<ny; ++j)
for(j=1; j<ny; ++j)//i的鄰接頂點入佇列
if(g[i][j])
{
pred[j]=-1;//-1表示遍歷到且是鄰接頂點
que[tail++]=j;
}
while(cur<tail)
{
y=que[cur];
if(cy[y]==-1) break;//找到一個未被匹配的點,則找到了一條交錯軌
++cur;
//for(j=0; j<ny; ++j)
for(j=1; j<ny; ++j)//y已經被匹配給cy[y]了,從cy[y]出發,將它的鄰接頂點入佇列
if(pred[j]==-2&&g[cy[y]][j])
{
pred[j]=y;
que[tail++]=j;
}
}
if(cur==tail) continue;//沒有找到交錯軌
while(pred[y]>-1)//更改交錯軌上的匹配狀態
{
cx[cy[pred[y]]]=y;
cy[y]=cy[pred[y]];
y=pred[y];
}
cy[y]=i;
cx[i]=y;
res++;
}
return res;
}
int main()
{
int k;
while(cin>>nx&&nx!=0)
{
cin>>ny>>k;
memset(g,0,sizeof(g));
int i,a,x,y;
for(i=0; i<k; ++i)
{
cin>>a>>x>>y;
g[x][y]=1;
}
cout<<MaxMatch()<<endl;
}
return 0;
}
/*
5 5 10
0 1 1
1 1 2
2 1 3
3 1 4
4 2 1
5 2 2
6 2 3
7 2 4
8 3 3
9 4 3
0
*/
相關文章
- POJ 3014:Asteroids(二分匹配,匈牙利演算法)AST演算法
- 圖論-二分圖匹配匈牙利演算法圖論演算法
- 二分圖最大匹配(匈牙利演算法)演算法
- 匈牙利演算法--二分圖的最大匹配演算法
- 詳解匈牙利演算法與二分圖匹配演算法
- 二分圖的最大匹配(匈牙利演算法)程式碼演算法
- POJ - 3041 Asteroids 【二分圖匹配】AST
- 匈牙利演算法模板(二分圖)演算法
- 對匈牙利演算法理解——對二分圖進行最大匹配的演算法演算法
- 求二部圖最大匹配的匈牙利演算法演算法
- 二分圖匹配
- 目標匹配:匈牙利演算法的python實現演算法Python
- 《啊哈!演算法》我要做月老 ——二分圖最大匹配演算法
- 二分圖最大權完美匹配
- 二分圖最小點覆蓋等於二分圖最大匹配
- 【UOJ78】二分圖最大匹配
- (最大流,二分圖的多重匹配) Magic Potion
- 洛谷P7368 [USACO05NOV] Asteroids G 題解 二分圖最小點覆蓋 匈牙利演算法AST演算法
- POJ 2749 二分 + 2-SAT
- 匈牙利演算法學習筆記演算法筆記
- POJ-3061 Subsequence(字首和+二分/尺取)
- HDU 2063 雲霄飛車(匈牙利演算法)演算法
- 匈牙利。
- POJ1743 Musical Theme(字尾陣列 二分)陣列
- (演算法競賽)簡單易懂二分圖演算法
- POJ 1611 The Suspects 圖論圖論
- 重學資料結構和演算法(三)之遞迴、二分、字串匹配資料結構演算法遞迴字串匹配
- 北大鄒磊:圖資料庫中的子圖匹配演算法資料庫演算法
- 圖解KMP字串匹配演算法+程式碼實現圖解KMP字串匹配演算法
- 二分演算法演算法
- 匈牙利演算法——海王們的渣男渣女行為演算法
- 聊聊二分演算法演算法
- 1.3二分演算法演算法
- POJ 3233 Matrix Power Series (矩陣快速冪+等比數列二分求和)矩陣
- 演算法基礎---二分演算法演算法
- 二分圖(例題)
- 二分圖補充
- 『筆記』二分圖筆記
- 演算法->二分查詢演算法