zoukankan      html  css  js  c++  java
  • hdu2282 Chocolate 完美匹配 + 拆点

    题意: 

      N个箱子排成一个圈,所有的箱子里的巧克力的数量加起来不大于N,每次可以把箱子里的巧克力向旁边的箱子转移(两个方向),问要让每个箱子里的巧克力不大于1的最小步数。

    分析:

      把巧克力大于1的箱子拆为 pi-1 个箱子(点),向没有巧克力的箱子建边,权值为最短距离。因为是一个圈,任意两点之间有两条路径,所以需要取小的一个值。X集合里的点的编号与原本图中的点无关,所以从0(1)开始,Y集合的点个数是N。

      拆点很新颖,在完美匹配中,这是第一次遇到。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 //O(m*m*n)
     8 const int N=1010, INF=0x3f3f3f3f;
     9 int Map[N][N],mat1[N],mat2[N];//匹配上的左右集合
    10 int KM(int m,int n)
    11 {
    12     int s[N],t[N],a[N],b[N];
    13     int i,j,k,p,q,ans=0;
    14     for(i=0;i<m;i++)
    15     {
    16         a[i]=-INF;
    17         for(j=0;j<n;j++)
    18             a[i]=Map[i][j]>a[i]?Map[i][j]:a[i];
    19         if(a[i]==-INF) return -1;//cannot match
    20     }
    21     memset(b,0,sizeof(b));
    22     memset(mat1,-1,sizeof(mat1));
    23     memset(mat2,-1,sizeof(mat2));
    24     for(i=0;i<m;i++)
    25     {
    26         memset(t,-1,sizeof(t));
    27         p=q=0;
    28         for(s[0]=i;p<=q&&mat1[i]<0;p++)
    29         {
    30             for(k=s[p],j=0;j<n&&mat1[i]<0;j++)
    31             {
    32                 if(a[k]+b[j]==Map[k][j]&&t[j]<0)
    33                 {
    34                     s[++q]=mat2[j]; t[j]=k;
    35                     if(s[q]<0)
    36                         for(p=j;p>=0;j=p)
    37                         {
    38                             mat2[j]=k=t[j];p=mat1[k]; mat1[k]=j;
    39                         }
    40                 }
    41             }
    42         }
    43         if(mat1[i]<0)
    44         {
    45             i--,p=INF;
    46             for(k=0;k<=q;k++)
    47             {
    48                 for(j=0;j<n;j++)
    49                     if(t[j]<0&&a[s[k]]+b[j]-Map[s[k]][j]<p)
    50                         p=a[s[k]]+b[j]-Map[s[k]][j];
    51             }
    52             for(j=0;j<n;j++) b[j]+=t[j]<0?0:p;
    53             for(k=0;k<=q;k++) a[s[k]]-=p;
    54         }
    55 }
    56     for(i=0;i<m;i++) ans+=Map[i][mat1[i]];
    57     return ans;
    58 }
    59 void init()
    60 {
    61     for(int i=0;i<N;i++)
    62         for(int j=0;j<N;j++)
    63              Map[i][j]=-INF;
    64 }
    65 int p[505];
    66 int main()
    67 {
    68     //freopen("test.txt","r",stdin);
    69     int n,m,i,j,k,a,b,t;
    70     while(scanf("%d",&n)!=EOF)
    71     {
    72         for(i=0;i<n;i++) scanf("%d",&p[i]);
    73         init();
    74         t=0;
    75         for(i=0;i<n;i++){
    76             if(p[i]<=1) continue;
    77             for(k=p[i];k>1;k--)
    78             {
    79                 for(j=0;j<n;j++){
    80                     if(!p[j]){
    81                         a=abs(j-i);
    82                         b=n-a;
    83                         a=min(a,b);
    84                         Map[t][j]=-a;
    85                     }
    86                 }
    87                 t++;
    88             }
    89         }
    90         //for(i=0; i<t;i++){for(j=0;j<n;j++) printf("%d ",Map[i][j]);printf("
    "); }
    91         printf("%d
    ",-KM(t,n));
    92     }
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    (组件、路由)懒加载
    vue.js实现用户评论、登录、注册、及修改信息功能
    vue 路由传参 params 与 query两种方式的区别
    WebSocket入门教程(五)-- WebSocket实例:简单多人聊天室
    js系列教程11-json、ajax(XMLHttpRequest)、comet、SSE、WebSocket全解
    回忆一下跨域
    Http,Socket,TCP/IP 协议简述
    Vue+WebSocket 实现页面实时刷新长连接
    微信小程序JS导出和导入
    Vue学习之路之登录注册实例代码
  • 原文地址:https://www.cnblogs.com/Potato-lover/p/3993628.html
Copyright © 2011-2022 走看看