机器调度
Problem Description
有两台机器A和B以及N个需要运行的任务。
机器A有N种不同的模式,机器B有M种不同的模式,而每个任务都恰好在一台机器上运行。如果它在机器A上运行,则机器A需要设置为模式ai,如果它在机器B上运行,则机器B需要设置为模式bj。
特别说明:
开始的时候,两台机器分别处于a0和b0模式。
每台机器上的任务可以按照任意顺序执行,但是每台机器每转换一次模式都需要重启一次。
请合理为每个任务安排一台机器并合理安排顺序,使得机器重启次数尽量少。
Input
输入包含多组测试用例。
每组输的第一行是三个正整数N,M(N,M < 100)和k(k < 1000)。
接下来k行表示k个任务,每个任务包括三个元素i,x,y,表示编号是i的任务(i从0开始编号),可以在机器A的第x个模式运行,也可以在机器B的第y个模式上运行。
N为0时,输入结束~
Output
请输出完成所有的任务,机器需要重启的最少次数。
每组数据输出一行。
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
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1005;
int leftn,rightn;
int g[MAXN][MAXN];
int linker[MAXN];
bool vis[MAXN];
bool dfs(int a)//判断合法性和回溯(就这么理解吧)
{
for(int i=0;i<leftn;i++)
{
if(g[a][i]==1&&!vis[i])
{
vis[i]=true;
if(linker[i]==-1||dfs(linker[i]))
{
linker[i]=a;
return true;
}
}
}
return false;
}
int hun()//匈牙利 算法
{
int sum=0;
memset(linker,-1,sizeof(linker));
for(int i=0;i<rightn;i++)
{
memset(vis,false,sizeof(vis));
if(dfs(i))
sum++;
}
return sum;
}
int main()
{
while(cin>>rightn&&rightn!=0)
{
int k;
cin>>leftn>>k;
memset(g,0,sizeof(g));
int id,left,right;
while(k--)
{
cin>>id>>left>>right;
if(left!=0&&right!=0)//这个是题目专门的特判
g[left][right]=1;//如果ok,则可以匹配(连线)
}
cout<<hun()<<endl;
}
return 0;
}
这个是最大匹配数,还有别的一些二分的东西都可以用匈牙利这么做