首页 > 其他分享 >CF1155F Delivery Oligopoly 警告与思考--zhengjun

CF1155F Delivery Oligopoly 警告与思考--zhengjun

时间:2023-07-21 13:34:50浏览次数:33  
标签:连通 Oligopoly -- memset Delivery int sizeof 分量

警告:

  • 注意区分【强连通分量】,【边双联通分量】,【点双连通分量】。

思考:

  • 之前没有做到过边双连通分量的拆解;

  • 一个边双联通分量可以看作一个基环上不断加一条链;

  • 注意,这里加的链首尾可以为同一个位置。

到这步代码就好弄了。

代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=14,M=1<<N,INF=1e9;
int n,m,U,a[N][N];
int f[N][M][N],g[M],h[N][M];
struct zj{
	int S,u,v;
}t[M];
void chkmin(int &x,int y,zj &a,zj b){
	if(x>y)x=y,a=b;
}
int ans[N][N];
void findf(int s,int S,int u){
	if(s==u)return;
	int v=f[s][S][u];
	ans[u][v]=1;
	findf(s,S^(1<<u),v);
}
void findh(int s,int S){
	int u=h[s][S];
	findf(s,S,u);
	ans[u][s]=1;
}
void findg(int S){
	int Q=t[S].S,u=t[S].u,v=t[S].v;
	if(!~v)findh(u,S);
	else if(u^v)findf(u,Q,v),findg(S^Q^(1<<u)^(1<<v));
	else findh(u,Q),findg(S^Q^(1<<u));
}
int main(){
	freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	cin>>n>>m,U=(1<<n)-1;
	for(int u,v;m--;){
		cin>>u>>v,u--,v--;
		a[u][v]=a[v][u]=1;
	}
	memset(f,-1,sizeof f),memset(h,-1,sizeof h);
	memset(t,-1,sizeof t);
	for(int s=0;s<n;s++){
		f[s][1<<s][s]=1;
		for(int S=0;S<=U;S++){
			for(int u=0;u<n;u++)if(S>>u&1){
				if(!~f[s][S][u])continue;
				for(int v=0;v<n;v++)if(~S>>v&1){
					if(a[u][v])f[s][S|(1<<v)][v]=u;
				}
				if(a[u][s]&&__builtin_popcount(S)>2)h[s][S]=u;
			}
		}
	}
	memset(g,0x3f,sizeof g);
	for(int S=0;S<=U;S++){
		for(int u=0;u<n;u++)if(S>>u&1){
			if(~h[u][S]){
				g[S]=__builtin_popcount(S),t[S].u=u;
			}
		}
	}
	for(int S=0;S<=U;S++){
		for(int T=S;T;--T&=S){
			int P=S^T,delta=__builtin_popcount(T)+1;
			if(g[P]>INF)continue;
			for(int u=0;u<n;u++)if(P>>u&1){
				for(int v=u;v<n;v++)if(P>>v&1){
					if(u^v){
						int Q=T|(1<<u)|(1<<v);
						if(!~f[u][Q][v])continue;
						chkmin(g[S],g[P]+delta,t[S],{Q,u,v});
					}else{
						int Q=T|(1<<u);
						if(!~h[u][Q])continue;
						chkmin(g[S],g[P]+delta,t[S],{Q,u,v});
					}
				}
			}
		}
	}
	cout<<g[U]<<endl;
	findg(U);
	for(int u=0;u<n;u++){
		for(int v=0;v<n;v++){
			if(ans[u][v]){
				printf("%d %d\n",u+1,v+1);
			}
		}
	}
	return 0;
}

标签:连通,Oligopoly,--,memset,Delivery,int,sizeof,分量
From: https://www.cnblogs.com/A-zjzj/p/17571036.html

相关文章

  • Linux常用操作
    前言记录一下工作中用到过的Linux操作。查看日志tail#实时监控日志tail-f文件名如:tail-finfo.log#查看日志尾部最后10行日志tail-n10stdout.loggrepgrep"要搜索的内容"文件名查看文件vimvim文件名#进入编辑模式1.i在光标处编辑2.A在当......
  • java学习day01
    Day01java笔记1.什么是程序程序:为了让计算机执行某些操作或者解决某个问题而编写的有序集合计算机语言(1)低级语言机器语言只认识01汇编语言(2)高级语言面向过程语言:c语言面向对象语言:java,python,c#等2.人机交互控制台常用命令:(1)切换盘符D:+回车(2)dir 查......
  • Debian12配置NTP时间同步
    环境查看系统版本:lsb_release-a配置NTP时间同步下面的配置需要用到管理员权限,可以使用su切换到管理员权限。查看/修正时区查看系统时区:timedatectl如果时区不是Asia/Shanghai需要修改时区为东八区root@debian:/home/test#timedatectlset-timezone"Asia/Shanghai"查......
  • C++实现公司设备管理系统
    1.1.1设计内容:编写一个简单的实验室设备管理程序,帮助管理实验室设备信息。要求具有设备信息管理的功能。其中包括设备信息的录入、删除、查询和修改等功能。还应包括对实验室信息管理的功能。其中包括对实验室信息的录入、删除、修改和查询等功能。1.2任务和要求运用面向对......
  • 判断点与多边形的关系(4):射线法
    https://blog.csdn.net/ezhchai/article/details/78867367终极大招来了,射线法是解决这一问题的最优方法,其他方法仅具有理论意义,如果工程应用的话,知道这个方法就够了。射线法的思想是:以目标点为端点引一条射线,计算这条射线和多边形所有边的交点数目。如果交点个数为奇数,则点在多边......
  • Tita 升级|绩效考核优化
    1.  【考核模板-流程设置】指标制定、上级确认、绩效面谈增加「虚线上级」Tita-OKR和新绩效一体化管理平台如下图所示:2.  【部门考核】HRBP新增考核管理功能(批量公布结果、重启考核)如下图所示:3.  【我评价的】考核列表增加已评价、未评价状态切换和筛选「我评......
  • leetcode872叶相似树
    这道题是考虑的深度优先搜索,使用递归vecotr和queue入队操作并不相同:vector只能使用push_back();queue既可以使用push()还可以使用push_back()voidFindLeaf(TreeNode*root,vector<int>&v){if(!root->left&&!root->right){v.push_back(root->val);re......
  • python excel 怎么换行列
    PythonExcel换行列的解决方案在处理Excel文件时,有时候需要将一列的数据进行换行操作,即将一列的数据拆分为多行显示。本文将介绍如何使用Python解决这个问题。准备工作首先,我们需要安装openpyxl库,它是一个用于处理Excel文件的Python库。可以使用以下命令进行安装:pipinstallop......
  • python sip freeswitch
    PythonSIPandFreeSWITCHIntroductionInthisarticle,wewillexplorehowtousePythontointeractwithFreeSWITCH,anopen-sourcetelephonyplatform.WewillspecificallyfocusonutilizingtheSessionInitiationProtocol(SIP)moduleinPythontoest......
  • python excel 去掉多列
    PythonExcel去掉多列实现方法引言在日常的数据处理工作中,经常会遇到需要处理Excel文件的情况,其中一项常见的操作是去掉不需要的列。本文将教你如何使用Python来实现去掉多列操作。整体流程以下是去掉多列的步骤概览:步骤描述步骤一打开Excel文件步骤二选择要去......