当前位置: 首页 > news >正文

图论1(许廷强)做题总结

CF1239E. Turtle

神秘贪心+dp题。
首先假设第一行和第二行所选的数已经定了,只用考虑摆放顺序。
\(w_i\)为从第\(i\)行拐入第二行的答案。
对于第一行,假设有\(a_{1,i}>a_{1,i+1}\)时,交换\(a_{1,i}\)\(a_{1,i+1}\),发现此时\(w_{1\sim i-1}\)不变,\(s_{i+1\sim n}\)也不变,只有\(w_i\)变小,所以答案会变小或不变,总之不会变劣。
所以第一行一定是\(a_{1,1}\)\(a_{1,n}\)从小到大排序,同理可得第二行一定是从大到小排序。
接下来可以研究\(w_i\)的差分数组\(c_i\)的单调性。
\(c_i=a_{1,i}-a_{2,i-1}\),所以\(c_i\)单调递增,所以\(w_i\)具有凸性,且顶点处为最小值,所以最大值仅会出现在\(w_1\)\(w_n\)之中。
发现\(w_1=\sum_{i=1}^{n}a_{2,i}+a_{1,1}=\sum_{i=1}^{2}\sum_{j=1}^{n}a_{i,j}-\sum_{i=1}^{n}a_{1,i}+a_{1,1}\)\(w_n=\sum_{i=1}^{n}a_{1,i}+a_{2,n}\)都只和第一列的和有关,故可以用DP来求出第一行数的所有可能以及方案,复杂度\(O(n\sum a)\)但我们还需要枚举\(a_{1,1}\)\(a_{2,n}\)复杂度需要多加\(n^2\),无法通过。
此时我们可以发现\(a_{1,1}\)\(a_{2,n}\)两个数在每一种路径中都会经过,所以取最小的两个数一定不劣。那么总时间就可以在\(O(n\sum a)\)
代码:

#include<bits/stdc++.h>
using namespace std;
#define il inline
struct IO
{static const int Size=(1<<21);char buf[Size],*p1,*p2;int st[105],Top;~IO(){clear();}il void clear(){fwrite(buf,1,Top,stdout);Top=0;}il char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,Size,stdin),p1==p2)?EOF:*p1++;}il void pc(const char c){Top==Size&&(clear(),0);buf[Top++]=c;}il IO& operator >>(char& c){while(c=gc(),c==' ' || c=='\n' || c=='\r');return *this;}template<typename T>il IO& operator >>(T& x){x=0;bool f=0;char c=gc();while(!isdigit(c)){if(c=='-') f=1;c=gc();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}f?x=-x:0;return *this;}il IO& operator >>(string& s){s="";char c=gc();while(c==' ' || c=='\n' || c=='\r') c=gc();while(c!=' ' && c!='\n' && c!='\r' && c!=EOF) s+=c,c=gc();return *this;}il IO& operator <<(const char c){pc(c);return *this;}template<typename T> il IO& operator <<(T x){if(x<0) pc('-'),x=-x;do st[++st[0]]=x%10,x/=10;while(x);while(st[0]) pc(st[st[0]--]+'0');return *this;}il IO& operator <<(const string s){for(auto c:s) pc(c);return *this;}il IO& operator <<(const char* c){for(int i=0;c[i];i++) pc(c[i]);return *this;}
} fin,fout;
const int N=30,inf=1e9;
int a[N<<1],dp[N][N<<16],pre[N][N<<16],vis[N<<1],ans[2][N];
signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);int n;fin>>n;for(int i=1;i<=n*2;i++) fin>>a[i];sort(a+1,a+1+2*n);dp[1][a[1]]=1;pre[1][a[1]]=1;for(int i=3;i<=2*n;i++){for(int j=n;j>=2;j--){for(int k=a[i];k<=a[2*n]*n;k++){if(dp[j][k]) continue;dp[j][k]|=dp[j-1][k-a[i]];if(dp[j-1][k-a[i]]) pre[j][k]=i;}}}int sum=0,mn=inf,idx=0;for(int i=1;i<=2*n;i++) sum+=a[i];for(int i=1;i<=min(n*a[n*2],sum);i++){if(!dp[n][i]) continue;int val=max(i+a[2],sum-i+a[1]);if(val<mn) idx=i,mn=val;}for(int i=n;i>=1;i--){vis[pre[i][idx]]=1;ans[0][i]=a[pre[i][idx]];idx-=a[pre[i][idx]];}int now=n;for(int i=1;i<=n*2;i++){if(!vis[i]) ans[1][now--]=a[i];}for(int i=0;i<=1;i++){for(int j=1;j<=n;j++) fout<<ans[i][j]<<" ";fout<<"\n";}return 0;
}

CF521E Cycling City

首先我们会发现符合条件的点对的样子大概是环上加一条边的这条边上的两个点。对于这种带环的图论题,第一反应是找出一个生成树然后再生成树树跑路径,手玩几组会发现如果两个路径有边的交集,那么就可以构造出一组解。大概长这个样子

其中绿色为树边,红黄蓝三色为三条路径,及重合树边一条,绕到第一条非树边上的一条,绕到第二条非树边上的一条。
代码实现是可以直接暴力,因没有重合时复杂度和枚举每条树边的复杂度相等,有重合就可以直接统计答案了。
代码:

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
struct IO
{static const int Size=(1<<21);char buf[Size],*p1,*p2;int st[105],Top;~IO(){clear();}il void clear(){fwrite(buf,1,Top,stdout);Top=0;}il char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,Size,stdin),p1==p2)?EOF:*p1++;}il void pc(const char c){Top==Size&&(clear(),0);buf[Top++]=c;}il IO& operator >>(char& c){while(c=gc(),c==' ' || c=='\n' || c=='\r');return *this;}template<typename T>il IO& operator >>(T& x){x=0;bool f=0;char c=gc();while(!isdigit(c)){if(c=='-') f=1;c=gc();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}f?x=-x:0;return *this;}il IO& operator >>(string& s){s="";char c=gc();while(c==' ' || c=='\n' || c=='\r') c=gc();while(c!=' ' && c!='\n' && c!='\r' && c!=EOF) s+=c,c=gc();return *this;}il IO& operator <<(const char c){pc(c);return *this;}template<typename T> il IO& operator <<(T x){if(x<0) pc('-'),x=-x;do st[++st[0]]=x%10,x/=10;while(x);while(st[0]) pc(st[st[0]--]+'0');return *this;}il IO& operator <<(const string s){for(auto c:s) pc(c);return *this;}il IO& operator <<(const char* c){for(int i=0;c[i];i++) pc(c[i]);return *this;}
} fin,fout;
const int N=200010;
int f[N],h[N],tot,vis[N],d[N],F[N],col[N],ff[20][N];
struct node
{int nxt,to;
} e[N<<1];
struct edge
{int u,v;
} E[N];
vector<int> huan[N];
void add(int u,int v)
{tot++;e[tot].to=v;e[tot].nxt=h[u];h[u]=tot;
}
int fnd(int x)
{if(f[x]==x) return x;return f[x]=fnd(f[x]);
}
void dfs(int u,int fa)
{d[u]=d[fa]+1;F[u]=fa;ff[0][u]=fa;for(int i=1;i<=19;i++) ff[i][u]=ff[i-1][ff[i-1][u]];for(int i=h[u];i;i=e[i].nxt){int v=e[i].to;if(v==fa) continue;dfs(v,u);}
}
int get_lca(int u,int v)
{if(d[u]<d[v]) swap(u,v);for(int i=19;i>=0;i--){if(d[ff[i][u]]>=d[v]) u=ff[i][u];}if(u==v) return u;for(int i=19;i>=0;i--){if(ff[i][u]!=ff[i][v]) u=ff[i][u],v=ff[i][v];}return ff[0][u];
}
signed main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);int n,m;fin>>n>>m;for(int i=1;i<=m;i++) fin>>E[i].u>>E[i].v;for(int i=1;i<=n;i++) f[i]=i;for(int i=1;i<=m;i++){int u=E[i].u,v=E[i].v;if(fnd(u)!=fnd(v)){vis[i]=1;f[fnd(u)]=fnd(v);add(u,v);add(v,u);}}for(int i=1;i<=n;i++) if(f[i]==i) dfs(i,0);vector<int> tmp,tmp2;for(int i=1;i<=m;i++){if(!vis[i]){int u=E[i].u,v=E[i].v,lca=get_lca(u,v);int idx=0,lst=0;while(u!=lca){huan[i].push_back(u);if(col[u] && !idx) idx=col[u];if(col[u] && col[u]==idx) tmp.push_back(u),lst=F[u];col[u]=i;u=F[u];}int fl=0;if(lst) tmp.push_back(lst);if(lst==lca) fl=1;huan[i].push_back(lca);vector<int> tmp3;lst=0;while(v!=lca){tmp3.push_back(v);if(col[v] && !idx) idx=col[v];if(col[v] && col[v]==idx) tmp2.push_back(v),lst=F[v];col[v]=i;v=F[v];}if(lst){if(lst!=lca) tmp2.push_back(lst);else if(!fl) tmp.push_back(lst);}reverse(tmp3.begin(),tmp3.end());for(int j:tmp3) huan[i].push_back(j);if(idx){fout<<"YES\n";reverse(tmp2.begin(),tmp2.end());for(int j:tmp2) tmp.push_back(j);fout<<tmp.size()<<" ";for(int j:tmp) fout<<j<<" ";fout<<"\n";vector<int> ans;u=tmp[0],v=tmp[(int)tmp.size()-1];reverse(huan[i].begin(),huan[i].end());fl=0;for(int j:huan[i]){if(j==u) fl=1;if(fl) ans.push_back(j);}for(int j:huan[i]){ans.push_back(j);if(j==v) break;}fout<<ans.size()<<" ";for(int j:ans) fout<<j<<" ";fout<<"\n";int idx1=0,idx2=0;for(int j=0;j<(int)huan[idx].size();j++){if(huan[idx][j]==u) idx1=j;if(huan[idx][j]==v) idx2=j;}if(idx1<idx2) reverse(huan[idx].begin(),huan[idx].end());vector<int> ().swap(ans);fl=0;for(int j:huan[idx]){if(j==u) fl=1;if(fl) ans.push_back(j);}for(int j:huan[idx]){ans.push_back(j);if(j==v) break;}fout<<ans.size()<<" ";for(int j:ans) fout<<j<<" ";fout<<"\n";return 0;}}}fout<<"NO";return 0;
}

CF1142E Pink Floyd

这是啥必做的交互吗。

http://www.jsqmd.com/news/726545/

相关文章:

  • ARM PMBMAR_EL1寄存器:性能监控与内存属性配置详解
  • 数聚大向和数聚股份有什么关系?并无关系!数聚大向为独立公司 - 速递信息
  • 玻璃棉卷毡优质厂家推荐榜 玻璃棉卷毡 离心玻璃棉卷毡 玻璃棉保温卷毡 公司优选 - 奔跑123
  • 终极RyzenAdj调优指南:3步解锁锐龙处理器隐藏性能
  • 在Python项目中集成Taotoken实现多模型智能对话的完整指南
  • 降AI率工具综合性价比TOP5实测:从90%降到4%的攻略秘籍全公开!
  • 2026年710nm窄带滤光片将有何新突破?带你一探究竟!
  • ​省心又省钱!快易播GEO发稿平台,解锁AI时代高效传播新路径 - 新闻快传
  • 激光衍射粒度分析仪哪家公司好 业内优质厂家推荐 - 品牌推荐大师
  • Claude HUD 插件详解 | 为 Claude Code 打造的仪表盘
  • 3步部署方案:开源内存注入技术实现英雄联盟皮肤自定义
  • ESXi 8.0下NVMe硬盘‘消失’了?别急,试试这个PCIe直通‘复活’大法(附性能对比)
  • SteamAutoCrack:自动化Steam游戏破解工具完全指南
  • 2026国内工业级田园管理机厂家实力排行:成峰等多维度解析 - 奔跑123
  • 硅酸铝针刺毯优质厂家推荐榜 硅酸铝针刺毯 硅酸铝防火包裹 公司优选 - 奔跑123
  • 如何快速优化游戏本性能:OmenSuperHub完整硬件控制指南
  • 从零基础到实战落地:2026年大模型完整学习路线(避坑版)
  • CANoe测试中,如何动态管理多个DBC文件?getNextCANdbName函数实战指南
  • 2026上海别墅装修综合测评:九维评分体系全面解析 - 速递信息
  • 5分钟掌握DLSS版本管理工具:免费提升游戏画质与性能的终极方案
  • 2026年3月水处理设备厂家推荐,反渗透设备/水处理设备/反渗透膜/混床设备/电渗析器/净水机,水处理设备公司口碑推荐 - 品牌推荐师
  • 如何3分钟完成Adobe全家桶激活:Adobe-GenP 3.0终极指南
  • 武汉管道疏通:武汉管道疏通打孔维修哪家好 - LYL仔仔
  • 如何在 Taotoken 平台管理你的 API Key 与访问权限
  • 2026年4月昆明推拉棚/遮阳棚/张拉膜结构/集装箱厂家哪家好,认准云南琦淼建筑工程有限公司 - 2026年企业推荐榜
  • 从20年积累到300万张图像:拆解思谋工业大模型IndustryGPT V1.0背后的数据炼金术
  • 口碑好的饭团机公司选择:企业采购决策5个关键要点解析
  • 揭秘Windows上的安卓应用安装黑科技:告别模拟器时代
  • 【Kubernetes PDB 主动驱逐保护】3 个配置陷阱与正确避坑指南
  • 轻集料混凝土优质厂家实测排行与性能对比 廊坊锦茂节能科技有限公司 厂家电话 - 奔跑123