• Wannafly camp Day1 A Birthday


    题意

      在蛋糕上插n支蜡烛,并把蛋糕分为m个区域,第i根蜡烛只能插在第ai个区域或第bi个区域,在一个区域内同时摆放x支蜡烛就要花费x2的时间。

      问摆放时间的最小值。

      n,m<=50

    题解

      很容易发现此题无法贪心,由于n和m非常小,考虑建图跑网络流。

      对于cost为参数的平方的题,可以采用拆成n个点,费用为1、3、5...具体建图为:源点向每个蛋糕连边,每个区域拆成n个点,向汇点连边,每个蛋糕向可以在的两个区域的所有点连边,第i条边的费用为2 * i - 1。跑最小费用最大流即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define N 5010
     5 #define inf 0x3f3f3f3f
     6 
     7 inline int read(){
     8     int x=0,f=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    11     return x*f;
    12 }
    13 
    14 int n,m,s,t,h[N],num=1,cost=0,price=0,mxflow=0;
    15 bool vis[N];
    16 struct edge{
    17     int to,next,w,c;
    18 }data[50010<<1];
    19 inline void add(int x,int y,int w,int c){
    20     data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].w=w;data[num].c=c;
    21     data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].w=0;data[num].c=-c;
    22 }
    23 inline int dinic(int x,int low){
    24     vis[x]=1;if(x==t){cost+=low*price;mxflow+=low;return low;}int tmp=low;
    25     for(int i=h[x];i;i=data[i].next){
    26         int y=data[i].to;if(vis[y]||!data[i].w||data[i].c) continue;
    27         int res=dinic(y,min(tmp,data[i].w));
    28         tmp-=res;data[i].w-=res;data[i^1].w+=res;
    29         if(!tmp) return low;
    30     }return low-tmp;
    31 }
    32 inline bool label(){
    33     int d=inf;
    34     for(int x=1;x<=n;++x){
    35         if(!vis[x]) continue;
    36         for(int i=h[x];i;i=data[i].next){
    37             int y=data[i].to;if(vis[y]) continue;
    38             if(data[i].w&&data[i].c<d) d=data[i].c;
    39         }
    40     }if(d==inf) return 0;
    41     for(int x=1;x<=n;++x){
    42         if(!vis[x]) continue;
    43         for(int i=h[x];i;i=data[i].next)
    44             data[i].c-=d,data[i^1].c+=d;
    45     }price+=d;return 1;
    46 }
    47 
    48 void mcmf()
    49 {
    50     do 
    51         do
    52             memset(vis,0,sizeof(vis));
    53         while(dinic(s,inf));
    54     while(label());
    55 }
    56 
    57 int main()
    58 {
    59     n = read();
    60     m = read();
    61     s = 1;
    62     t = n + n * m + 2;
    63     for (int j = 2; j <= n + 1; ++j)
    64     {
    65         int a = read(), b = read();
    66         add(s, j, 1, 0);
    67         for (int i = 1; i <= n; ++i)
    68         {
    69             add(j, n + (a - 1) * n + i + 1, 1, 2 * i - 1);
    70             add(j, n + (b - 1) * n + i + 1, 1, 2 * i - 1);
    71         }
    72     }
    73     for (int i = n + 2; i < t; ++i)
    74         add(i, t, 1, 0);
    75     n = n + n * m + 2;
    76     mcmf();
    77     printf("%d
    ", cost);
    78 
    79     return 0;
    80 }
  • 相关阅读:
    lhgdialogv3.13 使用点滴
    CheckBoxList 取值 及选中相关用法
    repeater 及 gridview 中绑定短日期
    数据库中日期大小的判断
    父子不同窗口间刷新传值
    子级Repeater获取父级Repeater绑定项的值
    vs.net 2010 web 项目中使用 webservice
    web打印实现方案 Lodop6.034 使用方法总结
    用 showModalDialog 方法回传数据到父页中去
    vs.net2010中使用 Ajax Control Toolkit
  • 原文地址:https://www.cnblogs.com/aseer/p/9459662.html
Copyright © 2020-2023  润新知