poj2400 KM演算法二分圖的完美匹配
http://poj.org/problem?id=2400
Description
Suppose some supervisors each get to hire a new person for their department. There are N people to be placed in these N departments. Each supervisor interviews all N people, and ranks them according to how much she wants each of them in her department (1 being
"really want" and N being "really don't want"). In turn, each of the N candidates ranks each of the supervisors as to how much that person would like to work for that supervisor (again, 1 is "really want to work for him/her" and N is "really don't want to
work for him/her"). Given the scores that each supervisor has for each candidate, and the scores each candidate has for each manager, write a computer program to determine the "best match" of candidates to supervisors. The "best match" is determined by finding
the distribution that leads to the highest overall (i.e. sum of) satisfaction for all people. The closer a person is to her number one choice, the better. If everyone gets their number one choice, the average difference will be 0.
Input
The first line of the input will contain a single integer greater than 0 specifying the number of test cases.
The next line will contain a single integer value N, 0 < N < 15, representing the number of supervisors (and the number of employees - there are N supervisors and N employees). The next N lines will be the preferences of each of the N supervisors. Each line will contain N integer entries (1 through N for employees 1 through N), each separated by a space character, that represents the preferences of that supervisor from most preferred to least preferred. More specifically, the first entry on the line will represent that supervisor's first choice, the second entry her second, and so on. The next N lines will be the preferences of the N employees, in the same format as the supervisors.
All lines of data in the input file will end with an empty line.
The next line will contain a single integer value N, 0 < N < 15, representing the number of supervisors (and the number of employees - there are N supervisors and N employees). The next N lines will be the preferences of each of the N supervisors. Each line will contain N integer entries (1 through N for employees 1 through N), each separated by a space character, that represents the preferences of that supervisor from most preferred to least preferred. More specifically, the first entry on the line will represent that supervisor's first choice, the second entry her second, and so on. The next N lines will be the preferences of the N employees, in the same format as the supervisors.
All lines of data in the input file will end with an empty line.
Output
For each test case, write the test case number (starting with 1) followed by the best average difference written to six digits of precision to the right of the decimal point. On the next line, show which best match it was (starting with 1). On the next N lines,
show each supervisor (starting with 1) followed by the employee with which she was matched (1 per line). NOTE: if there is more than one best match, matches should be listed in ascending permuted order (see sample output).
Separate each data set with an empty line.
Separate each data set with an empty line.
Sample Input
2 7 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 2 1 2 2 1 1 2 1 2
Sample Output
Data Set 1, Best average difference: 0.000000 Best Pairing 1 Supervisor 1 with Employee 1 Supervisor 2 with Employee 2 Supervisor 3 with Employee 3 Supervisor 4 with Employee 4 Supervisor 5 with Employee 5 Supervisor 6 with Employee 6 Supervisor 7 with Employee 7 Data Set 2, Best average difference: 0.250000 Best Pairing 1 Supervisor 1 with Employee 1 Supervisor 2 with Employee 2http://blog.csdn.net/wangjian8006/article/details/7950005
/*************************************************************************
**************************************************************************
KM演算法模板C++
作用:
求二分圖的最佳匹配
注意:
(1)for (i:1~n)for (j:1~n)scanf (w[i][j]);
w[i][j],表示左邊第i點匹配右邊第j點的價值。i,j:從1開始。
主函式呼叫:ans=KM(); ans的值即為所求。
(2)所求為最大完備匹配,若是求最小,則把邊的權值取相反數,跑一遍模板,
最後結果再取相反數即可。
**************************************************************************
*************************************************************************/
#include <stdio.h>
#include <string.h>
#define M 16
#define inf 0x3f3f3f3f
int n,nx,ny,sum,cost;
int link[M],lx[M],ly[M],slack[M];///lx,ly為頂標,nx,ny分別為x點集y點集的個數
int visx[M],visy[M],w[M][M],mark[M];
int DFS(int x)
{
visx[x] = 1;
for (int y = 1; y <= ny; y ++)
{
if (visy[y]) continue;
int t = lx[x] + ly[y] - w[x][y];
if (t == 0)
{
visy[y] = 1;
if (link[y] == -1||DFS(link[y]))
{
link[y] = x;
return 1;
}
}
else if (slack[y] > t) ///不在相等子圖中slack 取最小的
slack[y] = t;
}
return 0;
}
int KM()
{
int i,j;
memset (link,-1,sizeof(link));
memset (ly,0,sizeof(ly));
for (i = 1; i <= nx; i ++) ///lx初始化為與它關聯邊中最大的
for (j = 1,lx[i] = -inf; j <= ny; j ++)
if (w[i][j] > lx[i])
lx[i] = w[i][j];
for (int x = 1; x <= nx; x ++)
{
for (i = 1; i <= ny; i ++)
slack[i] = inf;
while (1)
{
memset (visx,0,sizeof(visx));
memset (visy,0,sizeof(visy));
if (DFS(x)) ///若成功(找到了增廣軌),則該點增廣完成,進入下一個點的增廣
break; ///若失敗(沒有找到增廣軌),則需要改變一些點的標號,使得圖中可行邊的數量增加。
///方法為:將所有在增廣軌中(就是在增廣過程中遍歷到)的X方點的標號全部減去一個常數d,
///所有在增廣軌中的Y方點的標號全部加上一個常數d
int d = inf;
for (i = 1; i <= ny; i ++)
if (!visy[i]&&d > slack[i])
d = slack[i];
for (i = 1; i <= nx; i ++)
if (visx[i])
lx[i] -= d;
for (i = 1; i <= ny; i ++) ///修改頂標後,要把所有不在交錯樹中的Y頂點的slack值都減去d
if (visy[i])
ly[i] += d;
else
slack[i] -= d;
}
}
int res = 0;
for (i = 1; i <= ny; i ++)
if (link[i] > -1)
res += w[link[i]][i];
return -res;
}
void dfs(int cap,int x)///全排列搜尋找出所有答案
{
if(x<-cost) return;
/// printf("**\n");
if(cap>n)
{
if(x!=-cost)return;
printf("Best Pairing %d\n",++sum);
for(int i=1;i<=n;i++)
printf("Supervisor %d with Employee %d\n",i,link[i]);
}
else
{
for(int i=1;i<=n;i++)
{
if(!mark[i])
{
mark[i]=1;
link[cap]=i;
dfs(cap+1,x+w[cap][i]);
mark[i]=0;
}
}
}
}
int main()
{
int T,tt=0;
scanf("%d",&T);
while(T--)
{
memset(w,0,sizeof(w));
scanf("%d",&n);
nx=ny=n;
for(int i=1;i<=n;i++)
{
for(int j=0;j<n;j++)
{
int x;
scanf("%d",&x);
w[x][i]-=j;
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<n;j++)
{
int x;
scanf("%d",&x);
w[i][x]-=j;
}
}
/**for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",w[i][j]);
}
printf("\n");
}
*/
cost=KM();
printf("Data Set %d, Best average difference: %.6lf\n",++tt,0.5*cost/n);
sum=0;
memset(mark,0,sizeof(mark));
dfs(1,0);
printf("\n");
}
return 0;
}
相關文章
- KM演算法——二分圖的最佳匹配演算法
- Uva11383 二分圖的完美匹配(深入理解KM演算法)演算法
- 二分圖的最大匹配、完美匹配和匈牙利演算法演算法
- hdu2255 二分圖的最佳匹配 KM演算法演算法
- POJ 3565 Ants (最小權完美匹配 KM演算法)演算法
- 二分圖最大權完美匹配
- 圖論-二分圖匹配匈牙利演算法圖論演算法
- 匈牙利演算法--二分圖的最大匹配演算法
- 二分圖的最大匹配的匈牙利演算法演算法
- 二分圖最大匹配(匈牙利演算法)演算法
- 二分圖匹配
- 二分圖的最大匹配(匈牙利演算法)程式碼演算法
- 詳解匈牙利演算法與二分圖匹配演算法
- 二分圖最大匹配問題匈牙利演算法演算法
- 《啊哈!演算法》我要做月老 ——二分圖最大匹配演算法
- HDU 2063 匈牙利演算法二分圖的最大匹配演算法
- POJ 1325-Machine Schedule(二分圖匹配-匈牙利演算法)Mac演算法
- UVA 11383 - Golden Tiger Claw【二分圖km原理】Go
- 對匈牙利演算法理解——對二分圖進行最大匹配的演算法演算法
- 演算法學習之路|二分圖的最大匹配—匈牙利演算法(Dfs實現)演算法
- 二分圖最小點覆蓋等於二分圖最大匹配
- KM演算法演算法
- POJ 1469-COURSES(二分圖匹配入門-匈牙利演算法)演算法
- hdu5090 匈牙利演算法二分圖最大匹配問題演算法
- HDU 2255-奔小康賺大錢(Kuhn-Munkras演算法/KM演算法-完備匹配下的最大權匹配)演算法
- POJ - 3041 Asteroids 【二分圖匹配】AST
- POJ 3041-Asteroids(二分圖匹配)AST
- KM演算法小記演算法
- 匈牙利演算法模板(二分圖)演算法
- 對KM演算法暫時性的理解演算法
- 學習筆記----KM演算法筆記演算法
- 地圖匹配演算法實踐地圖演算法
- BZOJ 1191 [HNOI2006]超級英雄Hero:二分圖匹配 匈牙利演算法演算法
- 求二部圖最大匹配的匈牙利演算法演算法
- POJ 3014:Asteroids(二分匹配,匈牙利演算法)AST演算法
- 北大鄒磊:圖資料庫中的子圖匹配演算法資料庫演算法
- (演算法競賽)簡單易懂二分圖演算法
- 重學資料結構和演算法(三)之遞迴、二分、字串匹配資料結構演算法遞迴字串匹配