K. Color Graph

题意:

给定一个简单图,点个数<=16,删去部分边后,使得该图中无边数为奇数得环,问剩下的边数最大为多少?

思路:

如果一个图中无奇数边的环,那么这个图一定是个二分图。只要枚举二分图的左部,统计所有从左部到右部的边个数,答案就是枚举出的所有边数的最大值。(因为最优解一定也是一个二分图,所以一定会被枚举到)

//赛后补题,只过样例,仅供参考
#include <bits/stdc++.h>
using namespace std;
const int maxn=105;
const int maxm=1e4+5;
struct edge{
int u,v;
}E[maxm];
int tot=0;
void addedge(int u,int v){
E[++tot].u=u;
E[tot].v=v;
}
int color[maxn];
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
int n,m;
scanf("%d%d",&n,&m);
fill(color,color+1+n,0);
tot=0;
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
}
int ans=0;
for(int meijv=0;meijv<=(1<<n)-1;meijv++){
int mj=meijv;
for(int i=1;i<=n;i++){
if(mj&1){
color[i]=1;
}
else color[i]=0;
mj>>=1;
}
int res=0;
for(int i=1;i<=tot;i++){
if(color[E[i].u]!=color[E[i].v]){
res++;
}
}
ans=max(ans,res);
}
printf("Case #%d: %d\n",kase,ans);
}
}

D. Spanning Tree Removal

题意:

给定一个n阶的完全图,每次操作是从图中移除一棵生成树的所有边,问最多能进行多少次这样的操作?输出操作次数和每次移除的生成树的边。

思路:

n阶完全图共有n*(n-1)/2条边,一棵生成树有n-1条边,很容易猜到能进行n/2次操作,接下来就是如何构造的问题。

下面给出一种直接构造的方法(奇数就孤立出一个点随便连即可)

//赛后补题,只过样例,仅供参考
#include <bits/stdc++.h>
using namespace std;
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
int n;
scanf("%d",&n);
printf("Case #%d: %d\n",kase,n/2);
if(n%2==0){
for(int i=1;i<=n/2;i++){
printf("%d %d\n",i,i+1);
for(int j=1;j<=n/2-1;j++){
int u=i+j;
int v=(u+n-j*2-1)%n+1;
printf("%d %d\n",u,v);
printf("%d %d\n",v,u+1);
}
}
}
else{
n--;
for(int i=1;i<=n/2;i++){
printf("%d %d\n",i,i+1);
for(int j=1;j<=n/2-1;j++){
int u=i+j;
int v=(u+n-j*2-1)%n+1;
printf("%d %d\n",u,v);
printf("%d %d\n",v,u+1);
}
printf("%d %d\n",i,n+1);
}
}
}
}

H. Tree Partition

题意:

给出一棵点权树,一个树的大小定义为所有点的权值和。问将一棵树分为k棵子树,如何分割才能使所有树的大小的最大值最小?

思路:

二分答案,已知最大连通子图的大小x后,只要在树上从树根向上dp子树的大小即可。如果一个子树u的大小大于x,则先选择u最大的儿子v切除(即切割边u,v),这样能保证剩下的部分大小尽可能地小。这样保证了图上所有的连通子图的都是小于x的,同时也是用贪心的方法选择切割方案(每个子树都尽可能地取到最大,使剩下部分尽可能小),得到的就是最小的切割次数。

实现方法:若判断发现一个节点u的权值大于x,则将他的儿子节点排序,从大到小依次删除,直到u的权值小于x。

//赛后还原,仅供参考
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
struct edge{
int v,next;
}E[maxn];
int head[maxn],tot;
void addedge(int u,int v){
E[++tot].v=v;
E[tot].next=head[u];
head[u]=tot;
}
ll a[maxn],sum[maxn];
int flag=0,cnt;
int n,k;
void dfs(int u,int fa,ll x){
sum[u]=a[u];
if(sum[u]>x||flag==0){
flag=0;
return;
}
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=fa){
dfs(v,u,x);
sum[u]+=sum[v];
}
}
if(sum[u]>x){
vector<ll>V;
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=fa){
V.push_back(sum[v]);
}
}
sort(V.begin(),V.end());
while(sum[u]>x){
cnt++;
sum[u]-=V.back();
V.pop_back();
}
}
if(cnt>k-1){
flag=0;
return;
}
}
bool check(ll x){
flag=1;cnt=0;
dfs(1,0,x);
// printf("%lld:%d\n",x,flag);
if(flag)
return 1;
else
return 0;
}
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
scanf("%d%d",&n,&k);
fill(head,head+1+n,0);
fill(sum,sum+1+n,0);
tot=0;
for(int i=1;i<=n-1;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
ll l=0,r=1e14+5;//左开右闭
while(r-l>1){
ll mid=(r+l+1)/2;
if(check(mid))
r=mid;
else
l=mid;
}
printf("Case #%d: %lld\n",kase,r);
}
}

E. Cave Escape

题意:

给定一个\(n * m\)的格子矩阵,其中有一个格子是起点,一个格子是终点。从起点开始移动,每次能移动到有相邻边的格子中,每个格子都有一个权值v,若从点a移动到点b,且b点未被访问过,则可以获得\(Va*Vb\)的收益,若移动到终点,可以选择先不出去,继续在图上乱走,问如何可以使得走出终点后获得得收益最大?(只需要输出最大收益即可)

思路:

很显然终点在哪是对答案完全没有影响的,只要在矩阵中乱走获得最大收益再出去即可。

我们可以将这个矩阵转化为一个无向图,图中的点就是矩阵的格点,相邻格点之间有一条边,长度为它们权值的乘积。只要在这个图上跑一遍最大生成树,树的大小就是最大收益。为什么起点也是对答案没有影响?因为要达到最大收益,最好的方法就是将图中每一个都遍历一遍,因为多遍历一个点是不会亏的,可以通过已经遍历到的任意点往新的点走来得到收益(已经遍历过的格子在矩阵中是连通的,可以到处转移),这不就是生成树吗?

//赛后补题,只过样例,仅供参考
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+5;
const int maxm=4e6+5;
struct edge{
int u,v;
ll w;
}E[maxm];
bool cmp(edge a,edge b){
return a.w>b.w;
}
int tot=0;
void addedge(int u,int v,ll w){
E[++tot].u=u;
E[tot].v=v;
E[tot].w=w;
}
int fa[maxn*maxn];
int n,m;
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
ll kruskal(){
for(int i=1;i<=n*m;i++){
fa[i]=i;
}
sort(E+1,E+1+tot,cmp);
int cnt=0;
ll ans=0;
for(int i=1;i<=tot;i++){
int u=E[i].u;
int v=E[i].v;
int fu=find(u);
int fv=find(v);
if(fu!=fv){
fa[fu]=fv;
ans+=E[i].w;
cnt++;
}
if(cnt==n*m-1)return ans;
}
}
ll x[maxn*maxn];
ll V[maxn][maxn];
int xx[]={1,0,0,-1};
int yy[]={0,1,-1,0};
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
int sr,sc,tr,tc;
scanf("%d%d%d%d%d%d",&n,&m,&sr,&sc,&tr,&tc);
tot=0;
ll A,B,C,P;
scanf("%lld%lld%lld%lld%lld%lld",&x[1],&x[2],&A,&B,&C,&P);
for(int i=3;i<=n*m;i++){
x[i]=(x[i-1]*A+x[i-2]*B+C)%P;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
V[i][j]=x[(i-1)*m+j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int pp=0;pp<4;pp++){
int it=i+xx[pp];
int jt=j+yy[pp];
int u=(i-1)*m+j;
int v=(it-1)*m+jt;
if(it>=1&&it<=n&&jt>=1&&jt<=m){
addedge(u,v,V[i][j]*V[it][jt]);
}
}
}
}
ll ans=kruskal();
printf("Case #%d: %lld\n",kase,ans);
}
}

B. Prefix Code

题意:

给出一系列数字,长度均小于10,问是否有一个数是其他数的前缀?

思路:

Trie树模板题。记录单词的终末,前缀包含的单词个数即可。若一个点是单词终末且前缀包含单词个数>1,则输出No。

//输入字串用s+1,函数调用用s
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int T[maxn][12];
int num[maxn];
int isend[maxn];
int tot=1;
void add(char *s){
int l=strlen(s+1);
int rt=1;
for(int i=1;i<=l;i++){
if(T[rt][s[i]-'0']==0){
T[rt][s[i]-'0']=++tot;
rt=tot;
}
else{
rt=T[rt][s[i]-'0'];
}
num[rt]++;
}
isend[rt]=1;
}
void init(){
for(int i=0;i<=tot;i++){
memset(T[i],0,sizeof(T[i]));
num[i]=isend[i]=0;
}
tot=1;
}
char s[15];
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
init();
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
add(s);
}
int flag=1;
for(int i=1;i<=tot;i++){
if(isend[i]&&num[i]>1){
flag=0;
break;
}
}
if(flag)
printf("Case #%d: Yes\n",kase);
else
printf("Case #%d: No\n",kase);
}
}

ICPC2019上海区域赛 部分题解(正在更新)的更多相关文章

  1. 2019 ICPC 上海区域赛总结

    2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...

  2. UVAlive7141 BombX 14年上海区域赛D题 线段树+离散化

    题意:一个无限大的棋盘, 有n个小兵, 给出了n个兵的坐标, 现在有一个长为width 高为height的炸弹放在棋盘上, 炸弹只能上下左右平移, 不能旋转. 且放炸弹的区域不能含有士兵, 炸弹可以一 ...

  3. 2018-2019 ACM-ICPC 徐州区域赛 部分题解

    题目链接:2018-2019 ACM-ICPC, Asia Xuzhou Regional Contest A. Rikka with Minimum Spanning Trees 题意: 给出一个随 ...

  4. ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem

    题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射. 学到了向量模板, ...

  5. UVALive 7148 LRIP 14年上海区域赛K题 树分治

    题意 n个点组成一棵树, 带有点权. 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D. 显然是树分治, 但是分治之后如何维护答案呢. 假设当前重心为g, 分别记录g出发不降路径的长度,以及 ...

  6. ICPC2019 亚洲区域赛 南京站

    蒟蒻终于打完了人生的第一场ICPC了. 终榜去星后rank36,AG,和AU差几十罚时了. 虽有遗憾但总体也是正常发挥了. 不愿再去对比赛做什么回顾,甚至很不愿去想.很多题已经在能力之外,即便是平常熟 ...

  7. UVALive 7146 (贪心+少许数据结构基础)2014acm/icpc区域赛上海站

    这是2014年上海区域赛的一道水题.请原谅我现在才发出来,因为我是在太懒了.当然,主要原因是我刚刚做出来. 其实去年我就已经看到这道题了,因为我参加的就是那一场.但是当时我们爆零,伤心的我就再也没有看 ...

  8. 2014年亚洲区域赛北京赛区现场赛A,D,H,I,K题解(hdu5112,5115,5119,5220,5122)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 下午在HDU上打了一下今年北京区域赛的重现,过了5题,看来单挑只能拿拿铜牌,呜呜. ...

  9. 【2013南京区域赛】部分题解 hdu4802—4812

    上周末打了一场训练赛,题目是13年南京区域赛的 这场题目有好几个本来应该是我擅长的,但是可能是太久没做比赛了各种小错误代码写的也丑各种warusn trush搞得人很不爽 全场题之一的1002也没有想 ...

随机推荐

  1. Windows Server 搭建企业无线认证(NPS搭建)

    现代企业无线网络是必备,移动办公更是需求日益剧增.而带来的无线网络安全隐患随之而来,也是面临着巨大的挑战.所以对无线网络做接入认证是现在企业很迫切的需求. 上一遍已经说明了Radius认证方案:htt ...

  2. ios UIWebView加载HTMLStr图文,关于图片宽高设置,webView内容实际高度的踩坑问题

    一.关于UIWebView 与 WKWebView 选取问题 从发布时间看: 2008年7月11日,在新一代iPhone3G正式发售当天,iPhone OS 2.0(iOS 2.0)推出,这时候就有U ...

  3. GetExtendedTcpTable

    https://blog.csdn.net/sky101010ws/article/details/55511501 AdjustTokenPrivileges function Library Ad ...

  4. mysql 注入绕过小特性

    1. 注释 Select /*多行(单行)注释*/ version(); Select version(); #单行注释 Select version(); -- 单行注释 (两划线之后必须有空格) ...

  5. canvas一个简单粗暴的中奖转盘

    最近在学canvas做动画,于是就写个转盘练下手.上个简陋的成果图(中间那个是转的指针,外面的圈是图片,懒得写了哈哈哈) 代码很简单,都注释了,直接上代码吧,嘤嘤嘤 html <body> ...

  6. Oracle Internals Notes Redo Write Triggers

    There are four conditions that cause LGWR to perform a redo write. When LGWR is idle, it sleeps on a ...

  7. LeetCode--044--通配符匹配(java)*

    给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). 两个字符串完全匹配才算 ...

  8. 英语单词deploy

    来源——https://www.docker.com/ Leading companies rely on our container platform to build, manage and se ...

  9. 108天南京银行完成不可能完成的新金融DevOps转型

    在2018云栖大会南京峰会企业研发云专场,由南京银行研发管理负责人吴攀带来了“云效助力新金融DevOps转型——南京银行实践之路”的主题分享.首先对南京银行的研发规模与成长做了介绍,对“鑫云+”的诞生 ...

  10. FastDFS搭建文件管理系统

    参考:https://www.cnblogs.com/chiangchou/p/fastdfs.html 目录: 一:FastDFS介绍 1:简介: FastDFS 是一个开源的高性能分布式文件系统( ...