POJ-2400 Supervisor, Supervisee 最小权匹配
2012-11-21 19:46
267 查看
题目链接:http://poj.org/problem?id=2400
话说光理解题意就搞了很久啊,说说题意吧:公司有n个管理者要招聘n个员工,所以每个管理者对每个员工进行面试,然后管理者和员工相互做出评价,每个管理者要对每个员工打分,同样每个员工要对每个管理者打分,分数越低评价越高,分数范围0,n-1。题目要求你对管理者和员工进行配对,要求所有配对的管理者和员工的分数之和最小,并且输出所有的情况。
这个题目的难点就是要求所有的情况,我一开始想的就是枚举全排列做了,但看到数据量n<15,枚举是O(n!),如果数据恶心点,那么也会超时!想了一天,实在是没有其他的方法啊!其实n<15也已经暗示了要枚举做的啊!DFS试试,果然63ms就A了!看来以后还得把题目看得透一点!回想自己做区预赛的题目,每次也是遇到时间复杂度理论上限铁定会超时的时候,都不敢动手,但赛后发现,其实很多是可以搞的,所以经验还有待加强啊! PS:这题数据是反的= =。
话说光理解题意就搞了很久啊,说说题意吧:公司有n个管理者要招聘n个员工,所以每个管理者对每个员工进行面试,然后管理者和员工相互做出评价,每个管理者要对每个员工打分,同样每个员工要对每个管理者打分,分数越低评价越高,分数范围0,n-1。题目要求你对管理者和员工进行配对,要求所有配对的管理者和员工的分数之和最小,并且输出所有的情况。
这个题目的难点就是要求所有的情况,我一开始想的就是枚举全排列做了,但看到数据量n<15,枚举是O(n!),如果数据恶心点,那么也会超时!想了一天,实在是没有其他的方法啊!其实n<15也已经暗示了要枚举做的啊!DFS试试,果然63ms就A了!看来以后还得把题目看得透一点!回想自己做区预赛的题目,每次也是遇到时间复杂度理论上限铁定会超时的时候,都不敢动手,但赛后发现,其实很多是可以搞的,所以经验还有待加强啊! PS:这题数据是反的= =。
//STATUS:G++_AC_63MS_716KB #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<iostream> #include<string> #include<algorithm> #include<vector> #include<queue> #include<stack> using namespace std; #define LL long long #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int MAX=20,INF=200000000; int w[MAX][MAX],S[MAX],T[MAX],lx[MAX],ly[MAX],A[MAX],y[MAX],vis[MAX]; int Tu,n,ans,anscou,slack; int match(int u) { int v,t; S[u]=1; for(v=1;v<=n;v++){ t=w[u][v]-lx[u]-ly[v]; if(!t){ if(!T[v]){ T[v]=1; if(!y[v] || match(y[v])){ y[v]=u; return 1; } } } else if(t<slack)slack=t; } return 0; } void KM() { int i,j,a; mem(ly,0); for(i=1;i<=n;i++){ lx[i]=w[i][1]; for(j=2;j<=n;j++) if(w[i][j]<lx[i])lx[i]=w[i][j]; } for(i=1;i<=n;i++){ while(1){ slack=INF; mem(S,0);mem(T,0); if(match(i))break; for(j=1;j<=n;j++){ if(S[j])lx[j]+=slack; if(T[j])ly[j]-=slack; } } } } void dfs(int cur,int s) { if(s>ans || (cur==n+1 && s!=ans))return ; int i; if(cur==n+1){ printf("Best Pairing %d\n",anscou++); for(i=1;i<=n;i++) printf("Supervisor %d with Employee %d\n",i,A[i]); return ; } for(i=1;i<=n;i++){ if(!vis[i]){ vis[i]=1; A[cur]=i; dfs(cur+1,s+w[cur][i]); vis[i]=0; } } } int main() { // freopen("in.txt","r",stdin); int i,j,t,k=1; scanf("%d",&Tu); while(Tu--) { mem(y,0); scanf("%d",&n); for(i=1;i<=n;i++){ for(j=0;j<n;j++){ scanf("%d",&t); w[t][i]=j; } } for(i=1;i<=n;i++){ for(j=0;j<n;j++){ scanf("%d",&t); w[i][t]+=j; } } KM(); for(ans=0,i=1;i<=n;i++) ans+=w[y[i]][i]; printf("Data Set %d, Best average difference: %.6f\n",k++,ans*0.5/n); anscou=1; mem(vis,0); dfs(1,0); if(Tu)putchar('\n'); } return 0; }
相关文章推荐
- 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)
- poj 2400 Supervisor, Supervisee 二分匹配 最小权完美匹配 KM算法
- 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)
- POJ 2400 Supervisor, Supervisee(KM+DFS找相同最佳匹配)
- POJ 2400 Supervisor, Supervisee (二分图最大权匹配)
- POJ-2400 Supervisor, Supervisee 带权值匹配+枚举所有匹配情况
- POJ 2400 Supervisor, Supervisee KM求最小权
- POJ-2400-Supervisor, Supervisee(KM+DFS)
- POJ 2400 Supervisor, Supervisee
- POJ 2400 最小权匹配
- poj 2400 Supervisor, Supervisee
- POJ 2400 Supervisor, Supervisee(KM)
- POJ 2400 Supervisor, Supervisee
- pku 2400 Supervisor, Supervisee KM求最小权匹配+DFS回溯解集
- poj 2400 Supervisor, Supervisee
- POJ 2400 Supervisor, Supervisee (KM + 回溯) - from lanshui_Yang
- POJ 2400 KM最小权匹配+输出所有匹配方案
- poj 2400(最小权匹配)
- poj 2400 Supervisor, Supervisee
- POJ 2400 Supervisor, Supervisee