LightOJ 1011 Marriage Ceremonies (二分图最优匹配 状态压缩+记忆化搜索)
来源:互联网 发布:网络与诸葛亮什么意思 编辑:程序博客网 时间:2024/05/16 06:47
题目链接:http://lightoj.com/volume_showproblem.php?problem=1011
题意:n男n女要结婚,给出好感度矩阵,i行j列表示i男对j女的好感度,求一夫一妻结婚后总的最大好感度。
思路:套了个KM算法的模板0.004s直接秒了……然后觉得可以用状态压缩+记忆化搜索来练练手,结果跑了0.256s。。。
网上貌似还有用费用流做的。
#include <cstdio>#include <cstring>#define max(a,b) ((a)>(b)?(a):(b))const int maxn = 1<<16;const int N=20;int data[N][N];int n;int dp[maxn];int DFS (int x, int d){ if (x == 0) return 0; if (dp[x]) return dp[x]; for (int i=0;i<n;i++) if (x&(1<<i)) dp[x] = max(DFS(x^(1<<i),d-1)+data[i+1][d],dp[x]); return dp[x];}int main (){#ifdef ONLINE_JUDGE#elsefreopen("read.txt","r",stdin);#endifint T;scanf("%d",&T);for (int Cas=1;Cas<=T;Cas++){ scanf("%d",&n); memset(dp,0,sizeof(dp)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) scanf("%d",&data[i][j]); printf("Case %d: %d\n",Cas,DFS((1<<n)-1,n)); } return 0;}
#include <cstdio>#include <cstring>#include <cmath>const int N=20; //每个集合的最大点数const int INF=0x3f3f3f3f;template<typename Type>class KM_Matrix //KM算法,邻接矩阵{//求最大匹配边的总长及相应匹配。若求最小,加边时加负值private:int nx,ny; //nx,ny分别为x点集y点集的个数int link[N]; //link[a]=b代表 y集合中的a与x集合中的b匹配Type slack[N]; //优化bool visx[N],visy[N];Type lx[N],ly[N],w[N][N]; //lx,ly为顶标,w[][]记录各边权值bool DFS (int x){visx[x]=true;for (int y=1;y<=ny;y++){if (visy[y])continue;Type t = lx[x] + ly[y] - w[x][y];if (t==0)//if (fabs(t)<1e-10) //注意精度{visy[y]=true;if (link[y] == -1 || DFS(link[y])){link[y] = x;return true;}}else if (slack[y] > t) //不在相等子图中slack 取最小的slack[y] = t;}return false;}public:void Init (int _nx,int _ny){nx=_nx;ny=_ny;memset (link,-1,sizeof(link));memset (ly,0,sizeof(ly));for (int i=0;i<=nx;i++) //初始化,注意修改for (int j=0;j<=ny;j++)w[i][j]=INF;}void Add (int u,int v,Type val) //加边{w[u][v]=val;}Type KM (){int i,j;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 (true){memset (visx,false,sizeof(visx));memset (visy,false,sizeof(visy));if (DFS(x)) //若成功(找到了增广轨),则该点增广完成,进入下一个点的增广break; //若失败(没有找到增广轨),则需要改变一些点的标号,使得图中可行边的数量增加。 //方法为:将所有在增广轨中(就是在增广过程中遍历到)的X方点的标号全部减去一个常数d, //所有在增广轨中的Y方点的标号全部加上一个常数dType d = INF;for (i=1;i<=ny;i++)if (visy[i]==false && 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值都减去dif (visy[i])ly[i] += d;elseslack[i] -= d;}}Type res=0;for (i=1;i<=ny;i++) //返回总长if (link[i] > -1)res += w[link[i]][i];return res;}void Output () //按照x集合的顺序输出匹配边的长度{for(int i=1;i<=nx;i++) for(int j=1;j<=ny;j++) if (link[j]==i) {printf("%d\n",j); break; } }};KM_Matrix<int> ob;int main (){#ifdef ONLINE_JUDGE#elsefreopen("read.txt","r",stdin);#endifint T,n;scanf("%d",&T);for (int Cas=1;Cas<=T;Cas++){scanf("%d",&n);ob.Init(n,n);int i,j,t;for (i=1;i<=n;i++)for (j=1;j<=n;j++){scanf("%d",&t);ob.Add(i,j,t);} printf ("Case %d: %d\n",Cas,ob.KM());}return 0;}/*In:4296 1997 5942 52 42 7266 58 6 8373 83 69 9728 81 54 40510 46 61 32 3998 84 67 4 532 77 49 83 1177 53 8 64 2315 61 24 14 96660 13 46 93 76 9833 77 57 35 83 2111 50 88 1 87 6154 78 73 4 39 9047 51 5 1 92 6034 3 24 31 47 52Out:Case 1: 155Case 2: 288Case 3: 401Case 4: 474*/
- LightOJ 1011 Marriage Ceremonies (二分图最优匹配 状态压缩+记忆化搜索)
- light oj 1011 - Marriage Ceremonies (状态压缩+记忆化搜索)
- lightoj 1011 - Marriage Ceremonies(状态压缩dp)
- LightOJ-1011-Marriage Ceremonies [状态压缩][DP]
- lightoj 1011 Marriage Ceremonies (状态压缩dp~)
- lightoj 1011 Marriage Ceremonies
- LightOJ 1011 - Marriage Ceremonies
- LightOJ 1011 Marriage Ceremonies
- LightOJ 1011 Marriage Ceremonies
- 1011 - Marriage Ceremonies[状态压缩dp]
- LightOJ 1011 - Marriage Ceremonies (dp)
- Light OJ 1011 Marriage Ceremonies 状态压缩DP
- lightoj 1184 Marriage Media [二分图匹配]
- 【DP】 LightOJ 1011 - Marriage Ceremonies状压
- LightOJ 1011 Marriage Ceremonies【状压DP】
- LightOJ 1011 - Marriage Ceremonies (状压dp)
- LightOJ - 1011 Marriage Ceremonies(状压DP)
- LightOJ 1011 - Marriage Ceremonies(dp)
- PHP变量内存分配问题
- android 调用剪切板传递文本
- 计算机体系结构1_内存类型
- Birthday Cake UVA10167
- Android SDK Manager更新不了的解决办法
- LightOJ 1011 Marriage Ceremonies (二分图最优匹配 状态压缩+记忆化搜索)
- rtx任务间通信--信号量
- TED:逃出教育的“死亡谷”
- 软考-只是一次考试吗?
- 棋盘覆盖问题
- 计算圆周率 Pi (π)值, 精确到小数点后 10000 位 只需要 30 多句代码!
- rtx任务间通信--互斥量
- 架构师的责任
- 揭开Socket编程的面纱