BZOJ4479 : [Jsoi2013]吃货jyy

若$k\leq 15$,那么可以设$d[i][S]$表示经过了$S$集合的边,现在位于$i$点的最短路。

可以用Dijkstra算法在$O(n^22^k)$时间内求出。

否则若$k>15$,那么最坏情况下,它们会形成一个团,将这$k$条边连上后,图中最多剩下$7$个连通块。

如果知道哪些边要走,哪些边不走的话,那么只要存在欧拉回路就可以。

也就是说,所有点的度数都是偶数,且从$1$出发可以到达$k$条边的端点。

于是考虑DP,设$f[i][j][k]$表示考虑前$i$条边,目前连通性为$j$,每个点度数的奇偶性为$k$的最小代价。

时间复杂度$O(n^2Bell(7)2^n)$,状态比较稀疏,可以通过。

#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
typedef pair<int,int>P;
typedef pair<int,P>PI;
typedef long long ll;
const int N=13,M=880,inf=100000000,LIM=15;
int n,m,K,o,i,j,k,x,y,z;
inline void up(int&a,int b){a>b?(a=b):0;}
namespace SMALL{
int f[N][N][2],g[N][N],d[N][1<<LIM];priority_queue<PI,vector<PI>,greater<PI> >q;
inline void ext(int x,int y,int z){
  if(d[x][y]<=z)return;
  q.push(PI(d[x][y]=z,P(x,y)));
}
void solve(){
  for(i=0;i<n;i++)for(j=0;j<n;j++)f[i][j][0]=-1;
  for(i=0;i<n;i++)for(j=0;j<n;j++)g[i][j]=inf;
  for(i=0;i<K;i++){
    scanf("%d%d%d",&x,&y,&z);x--,y--;
    f[x][y][0]=f[y][x][0]=i;
    f[x][y][1]=f[y][x][1]=z;
  }
  scanf("%d",&m);
  while(m--){
    scanf("%d%d%d",&x,&y,&z);x--,y--;
    up(g[x][y],z),up(g[y][x],z);
  }
  for(i=0;i<n;i++)for(j=0;j<1<<K;j++)d[i][j]=inf;
  ext(0,0,0);
  while(!q.empty()){
    PI t=q.top();q.pop();
    x=t.second.first,y=t.second.second,z=t.first;
    if(z>d[x][y])continue;
    for(i=0;i<n;i++){
      if(~f[x][i][0])ext(i,y|(1<<f[x][i][0]),z+f[x][i][1]);
      ext(i,y,z+g[x][i]);
    }
  }
  printf("%d",d[0][(1<<K)-1]);
}
}
namespace BIG{
bool must[N];
int a[N],h,t,e[N][N],dp[2][1<<N],g[M][N][N],ans=inf;
int w[2][M][1<<N];
char T,v[2][M][1<<N];
short s[2][M][1<<N],cnt[2][M];
ll q[M];
map<ll,int>id;
inline void merge(int x,int y){
  x=a[x],y=a[y];
  for(int i=0;i<n;i++)if(a[i]==x)a[i]=y;
}
inline ll encode(){
  int i,m=0;ll t=0;
  static int v[N];
  for(i=0;i<n;i++)v[a[i]]=-1;
  for(i=0;i<n;i++){
    if(v[a[i]]<0)v[a[i]]=m++;
    t=t<<4|v[a[i]];
  }
  return t;
}
inline void decode(ll f){for(int i=n-1;~i;i--)a[i]=f&15,f>>=4;}
inline bool check(ll f){
  decode(f);
  for(int i=0;i<n;i++)if(must[i]&&a[i]!=a[0])return 0;
  return 1;
}
inline int ext(ll x){
  int&o=id[x];
  if(o)return o;
  q[o=++t]=x;
  return o;
}
inline void clr(){
  T++;
  for(int i=1;i<=t;i++)cnt[o^1][i]=0;
}
inline void add(int x,int y,int z){
  if(z>=inf)return;
  if(v[o^1][x][y]<T){
    v[o^1][x][y]=T;
    w[o^1][x][y]=z;
    s[o^1][x][cnt[o^1][x]++]=y;
    return;
  }
  up(w[o^1][x][y],z);
}
void solve(){
  for(i=0;i<n;i++)a[i]=i;
  for(i=1;i<1<<n;i++)dp[0][i]=inf;
  while(K--){
    scanf("%d%d%d",&x,&y,&z);x--,y--;
    must[x]=must[y]=1;
    merge(x,y);
    for(i=0;i<1<<n;i++)dp[o^1][i]=inf;
    for(i=0;i<1<<n;i++)if(dp[o][i]<inf){
      up(dp[o^1][i^(1<<x)^(1<<y)],dp[o][i]+z);
      up(dp[o^1][i],dp[o][i]+z+z);
    }
    o^=1;
  }
  decode(encode());
  h=1;
  ext(encode());
  while(h<=t){
    ll x=q[h];
    for(i=0;i<n;i++)for(j=0;j<n;j++){
      decode(x);
      merge(i,j);
      g[h][i][j]=ext(encode());
    }
    h++;
  }
  scanf("%d",&m);
  for(i=0;i<n;i++)for(j=0;j<n;j++)e[i][j]=inf;
  while(m--){
    scanf("%d%d%d",&x,&y,&z);x--,y--;
    if(x==y)continue;
    if(x>y)swap(x,y);
    up(e[x][y],z);
  }
  clr();
  for(i=0;i<1<<n;i++)add(1,i,dp[o][i]);
  o^=1;
  for(x=0;x<n;x++)for(y=0;y<n;y++)if(e[x][y]<inf){
    z=e[x][y];
    clr();
    for(i=1;i<=t;i++)for(j=0;j<cnt[o][i];j++){
      int S=s[o][i][j],f=w[o][i][S];
      add(i,S,f);
      add(g[i][x][y],S^(1<<x)^(1<<y),f+z);
      add(g[i][x][y],S,f+z+z);
    }
    o^=1;
  }
  for(i=1;i<=t;i++)if(check(q[i]))for(j=0;j<cnt[o][i];j++)if(!s[o][i][j])up(ans,w[o][i][0]);
  printf("%d",ans);
}
}
int main(){
  scanf("%d%d",&n,&K);
  if(!K)return puts("0"),0;
  if(K<=LIM)SMALL::solve();else BIG::solve();
  return 0;
}

  

时间: 2024-12-28 11:32:21

BZOJ4479 : [Jsoi2013]吃货jyy的相关文章

房上的猫:吃货联盟项目

一.首先先定义部分成员变量: String[] name = new String[4];// 订餐人 String[] greens = new String[4];// 储存菜品名称 String[] green = { "红烧带鱼", "鱼香肉丝", "时令鲜蔬" };// 菜品 int[] num = new int[4];// 份数 int[] time = new int[4];// 时间 String[] site = new St

吃货如何理解线性规划的对偶

1. 啥是对偶 对偶(duality)本身是一种非常普遍的概念,在生活中非常常见.比如你在吃一个甜筒冰激凌,为了能吃出一个洞来,你先从上面吃,然后再从下面吃,最后终于被你吃出了一个洞!当然这是玩笑了,下面是一个严肃的例子.比如爬山的时候一个大台阶你先上去了,回头拉你的女朋友上来,这时候就出现了一个标准的对偶:你把手尽力往下伸(最小化),而她把手尽力往上伸(最大化),最后终于碰到一起了(强对偶定理).这个过程中,你的手的高度总是高于或等于女朋友的手(弱对偶定理).线性规划中对偶的格式非常固定,但是

3星|《食品信息图》:英国吃货写的食品百科,信息图水平一般

本书是从英国吃货写的信息百科,科学的成分不多,基本内容是食物在世界各地的类别与做法的异同. 作者是个人不是组织,不够权威. 另外内容当然是以英国.欧洲的食物为主,作者对中国的食物非常不熟悉. 翻译水平一般,比如书中说苹果梨12年出现的,估计是另外一种类似的水果.有些内容明显是被译者改过,比如这个标题:“茄子:照相时请叫我”: 书中的信息图水平一般. 装帧精美,但是拿在手里太沉,阅读体验并不好. 以下是书中一些信息的摘抄.[]中是我的点评. 1:这种看起来土掉渣的块茎,其实是位列玉米.小麦和水稻之

以吃货的角度去理解云计算中On-Premise、IaaS、PaaS和SaaS

了解云计算的一定都听过四个“高大上”的概念:On-Premise(本地部署),IaaS(基础设施及服务).PaaS(平台即服务)和SaaS(软件即服务),这几个术语并不好理解.不过,如果你是个吃货,还喜欢汉堡,那这个问题就好解决了! 如果我想吃汉堡,有几种方法呢? 1.自己买材料自己做 准备烤箱,准备火腿,准备面粉,准备青菜,然后自己和面,加材料,加热等等.其要求动手能力比较强,比较难做,但是,您可以根据自己的口味,做出符合自己味道的汉堡.这就是On-Premise(本地部署). 典型代表:物理

JAVA吃货联盟项目。

1基础通过数组.选择结构.循环等实 现吃货联盟订餐系统. 1.我要订餐: 2.查看餐袋: 3.签收订单: 4.删除订单: 5.我要点赞: 6.退出系统: public class Doy001 { public static void main(String[] args) { Scanner input = new Scanner(System.in); String[] names = new String[4]; String[] dishMegs = new String[4]; int

OSChina 周一乱弹 —— 英雄救肉,才是真吃货!

一大清早小小编就看到这样一条动弹,顿时不能同意更多~ @Mallon:That's deep- 以后这就是小小编的人生信条了!要贯彻到底! 不过对于那些长期失眠的人来说就是另外一回事了 @ 孔小菜:如果做了亏心事真的会睡不着,那么本来就失眠的人,为什么不干脆去做点亏心事呢? @lieefu:傻子偷乞丐的钱包,被瞎子看到了,哑巴大吼一声,把聋子吓了一跳,驼子挺身而出,瘸子飞起一脚,通辑犯要拉他去公安局,麻子说,看我的面子算了. 女神跟你聊天时,聊到什么让你最痛苦呢? @fastpx2014:女神突

吃货联盟项目

public class ddddd { String []name =new String[4];//保存订单人姓名 String []dishMegs =new String[4];//保存所选信息,包括菜品名及份数 String []time =new String[4];//保存送餐时间 String[]address =new String[4];//保存送餐地址 int[]states =new int[4];//保存订单状态:0表预订.1表示完成 double []sumPrice

案例&gt;&gt;&gt;吃货联盟订餐

import java.util.Scanner; public class VersionAlliance { public static void main(String[] args) { Scanner input = new Scanner(System.in); String[] names = new String[4]; // 保存订餐人姓名 String[] dishMegs = new String[4]; // 保存菜名和分数的所选信息 String[] addresses

云计算 IaaS,SaaS,PaaS的区别?一个通俗易懂的吃货文章

来自一篇吃货文章了: ———————————————————— &lt;img src="https://pic2.zhimg.com/a55676f8e1b084a398f8cd5f85cdae7d_b.png" data-rawwidth="714" data-rawheight="431" class="origin_image zh-lightbox-thumb" width="714" d