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狀態。
為了完成作業,機器必須不斷的切換模式,試著寫程式實現:改變機器的順序,給每個作業分配合適的作業,使得重啟機器次數最少。
解題思路:
構造二部圖,用匈牙利演算法做二分圖匹配。
如果某作業任務可以在A的i狀態和B的j狀態上完成,則從Ai到Bj連一條邊,這樣構造二部圖。
對於樣例來說,選擇A狀態的1和2,B狀態的3。
DFS和BFS效率和記憶體幾乎完全一樣…
①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 1469-COURSES(二分圖匹配入門-匈牙利演算法)演算法
- 二分圖的最大匹配、完美匹配和匈牙利演算法演算法
- 詳解匈牙利演算法與二分圖匹配演算法
- 二分圖的最大匹配的匈牙利演算法演算法
- 二分圖最大匹配問題匈牙利演算法演算法
- POJ 3014:Asteroids(二分匹配,匈牙利演算法)AST演算法
- HDU 2063 匈牙利演算法二分圖的最大匹配演算法
- hdu5090 匈牙利演算法二分圖最大匹配問題演算法
- poj2400 KM演算法二分圖的完美匹配演算法
- 對匈牙利演算法理解——對二分圖進行最大匹配的演算法演算法
- 演算法學習之路|二分圖的最大匹配—匈牙利演算法(Dfs實現)演算法
- POJ - 3041 Asteroids 【二分圖匹配】AST
- POJ 3041-Asteroids(二分圖匹配)AST
- 求二部圖最大匹配的匈牙利演算法演算法
- BZOJ 1191 [HNOI2006]超級英雄Hero:二分圖匹配 匈牙利演算法演算法
- KM演算法——二分圖的最佳匹配演算法
- 《啊哈!演算法》我要做月老 ——二分圖最大匹配演算法
- 目標匹配:匈牙利演算法的python實現演算法Python
- hdu2255 二分圖的最佳匹配 KM演算法演算法
- 匈牙利演算法演算法
- Uva11383 二分圖的完美匹配(深入理解KM演算法)演算法
- POJ 3565 Ants (最小權完美匹配 KM演算法)演算法
- 推公式+二分--poj1759公式
- POJ-3461 Oulipo-匹配的字元有幾個(KMP演算法)字元KMP演算法
- 匈牙利演算法學習筆記演算法筆記
- 地圖匹配演算法實踐地圖演算法
- 【演算法題】任務分配問題---匈牙利演算法演算法
- (演算法競賽)簡單易懂二分圖演算法
- POJ 基本演算法演算法
- 重學資料結構和演算法(三)之遞迴、二分、字串匹配資料結構演算法遞迴字串匹配
- POJ 2955-Brackets(括號匹配-區間DP)Racket
- BZOJ 1059 [ZJOI2007]矩陣遊戲:二分圖匹配矩陣遊戲
- hihocoder 1158 質數相關(二分圖匹配 最大獨立集)
- POJ 3233 Matrix Power Series(矩陣+二分)矩陣
- POJ-2192 Zipper-順序合成串匹配
- 二分演算法演算法
- HDU 2063 雲霄飛車(匈牙利演算法)演算法
- 匈牙利演算法——海王們的渣男渣女行為演算法